ViewModel:
变量:List<Product>Products//在构造函数中获取数据。
      Product Product//与View层的ListView中的选中行SelectItem绑定。
      Product NewProduct//与View层与选中行对应的文本框绑定。在ViewModel中Product的Set属性中把value赋值给NewProduct我要的实现:
    在View层的列表选中某行后,在下边的文本框显示选中行的数据。然后可以任意修改文本框的数据,点击按钮后在更新。我的做法:
    列表的选中行绑定Product,每个文本框绑定Product的属性值,可以映射,但是只要更改数据后焦点离开,他就会把列表数据给更改成文本框中的数值。一开始的解决:
    我在ViewModel定义了NewProduct,让他绑定每个文本框,然后再Product的Set中把value给他赋值,可是还是只要焦点一离开,他就立即更改列表数据。我的问题:
    1,我怀疑是不是WPF的机制是:一个数据他是所有控件和变量共享的,我只从Model层获取了一次数据给Products,然后Product的值是根据选中行绑定的,NewProduct是从Product赋值过来的,操作的都是一条数据,随意有任何更改,他就自动全都更改了?
    2,如何点击按钮后在更新,而不是自动更新?
代码:
1,ListView数据源绑定Products,选中行绑定Product
     <ListView x:Name="ListView1" Grid.Row="2" Grid.ColumnSpan="3" Grid.Column="0" SelectedItem="{Binding Path=Product}" ItemsSource="{Binding Path=Products}" >
            <ListView.Resources>
                <Style TargetType="{x:Type ListViewItem}">
                    <!--<EventSetter Event="PreviewMouseDown" Handler="ListViewItem_PreviewMouseDownMouseDown"/>-->
                    <!--<Setter Property="class:ViewModel1.ProductViewModel.ItemClickProperty" />-->
                </Style>
            </ListView.Resources>
            <ListView.View>
                <GridView>
                    <GridViewColumn Header="ID" DisplayMemberBinding="{Binding Id}" Width="50"/>
                    <GridViewColumn Header="Name" DisplayMemberBinding="{Binding Name}" Width="100"/>
                    <GridViewColumn Header="Type" DisplayMemberBinding="{Binding Type}" Width="100"/>
                    <GridViewColumn Header="Price" DisplayMemberBinding="{Binding Price}" Width="100"/>
                    <GridViewColumn Header="Stock" DisplayMemberBinding="{Binding Stock}" Width="100"/>
                    <GridViewColumn Header="IsYesOrNo" DisplayMemberBinding="{Binding IsYesOrNo}" Width="100"/>
                </GridView>
            </ListView.View>
        </ListView>2,文本框绑定NewProduct
<Canvas HorizontalAlignment="Left" Height="35" Margin="5" VerticalAlignment="Center">
                <TextBlock Canvas.Left="100" Width="50">名称:</TextBlock>
                <TextBox Canvas.Left="150" Width="200" Text="{Binding Path=NewProduct.Name}"></TextBox>
            </Canvas>            <Canvas HorizontalAlignment="Left" Height="35" Margin="5" VerticalAlignment="Center" >
                <TextBlock Canvas.Left="100" Width="50">类型:</TextBlock>
                <ComboBox Canvas.Left="150" Width="200" ItemsSource="{Binding Path=ProductTypes}" Text="{Binding Path=Type, Mode=OneWay}" SelectedItem="{Binding Path=Type}"></ComboBox>
            </Canvas>            <Canvas HorizontalAlignment="Left" Height="35" Margin="5" VerticalAlignment="Center">
                <TextBlock Canvas.Left="100" Width="50">库存:</TextBlock>
                <TextBox Canvas.Left="150" Width="200" Text="{Binding Path=NewProduct.Stock}"></TextBox>
            </Canvas>            <Canvas HorizontalAlignment="Left" Height="35" Margin="5" VerticalAlignment="Center">
                <TextBlock Canvas.Left="100" Width="50">价格:</TextBlock>
                <TextBox Canvas.Left="150" Width="200" Text="{Binding Path=NewProduct.Price}"></TextBox>
            </Canvas>            <Canvas HorizontalAlignment="Left" Height="35" Margin="5" VerticalAlignment="Center">
                <Button Canvas.Left="125" Command="{Binding UpdateProduct}" >修改</Button>
            </Canvas>3,在Product的Set中给NewProduct赋值:
public Product Product
        {
            get { return _product; }
            set
            {
                _product = value;                //ProductType = _product.Type.ToString();
                NewProduct = _product;
                OnPropertyChanged("Product");
            }
        }
4,构造函数中给Products绑定数据,并给Product绑定数据默认为选中第一个:
            Products = productRepository.GetInstance();
            Product = _products[0];5,图例:
选中雪碧修改雪碧名称焦点到库存,此时没有点击修改按钮,就自动更新了,为什么?

解决方案 »

  1.   

    大体读了一下:首先你的怀疑是对的。你的编辑对话框里的对象和你ListView里选中的对象是同一个,因此改变这个对象会使所有绑定到它上面的UI发生变化,但前提是此对象实现了INotifyPropertyChanged接口,并且调用OnPropertyChanged函数——显然你给的例子里你应该是这么做了。至于你说的问题,其实是跟UpdatePropertyTrigger有关的。我记得默认的是LostFocus,也就是说,更新数据是在控件失去焦点之后。按照你的要求,你可以使用UpdatePropertyTrigger="Explicit",即更新数据是由你手动操控的。XAML: Text="{Binding Path=NewProduct.Price, UpdatePropertyTrigger=Explicit}"这里讲不了太细,点到为止,你需要自己去看一下http://msdn.microsoft.com/en-us/library/system.windows.data.binding.updatesourcetrigger.aspx