WPF Master \ Detail:如何在编辑细节时保持Master不更新?

时间:2014-08-14 12:12:22

标签: c# wpf mvvm datagrid

我有一个非常直接的MVVM Master \ Detail窗口 -

XAML代码段:                                                                     

        <Grid Grid.Row="0" Grid.Column="0" >
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="Auto"/>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition Width="*"/>
            </Grid.ColumnDefinitions>

            <Label Content="ID:" Grid.Row="0" Grid.Column="0"/>
            <Label Content="{Binding SelectedCustomer.CustId}" Grid.Row="0" Grid.Column="1"/>

            <Label Content="Name:" Grid.Row="1" Grid.Column="0"/>
            <TextBox Text="{Binding SelectedCustomer.Name}"  Grid.Row="1" Grid.Column="1"/>

            <Label Content="Address:" Grid.Row="2" Grid.Column="0"/>
            <TextBox Text="{Binding SelectedCustomer.Address}"  Grid.Row="2" Grid.Column="1"/>
            <Label Content="City:" Grid.Row="3" Grid.Column="0"/>
            <TextBox Text="{Binding SelectedCustomer.City}"  Grid.Row="3" Grid.Column="1"/>
            <Label Content="State:" Grid.Row="4" Grid.Column="0"/>
            <TextBox Text="{Binding SelectedCustomer.State}"  Grid.Row="4" Grid.Column="1"/>
            <Label Content="ZIP:" Grid.Row="5" Grid.Column="0"/>
            <TextBox Text="{Binding SelectedCustomer.ZIP}"  Grid.Row="5" Grid.Column="1"/>

        </Grid>

        <Grid Grid.Row="1" Grid.Column="0">
            <DataGrid ItemsSource="{Binding CustomerCollection}" SelectedItem="{Binding SelectedCustomer}"></DataGrid>
        </Grid>
    </Grid>

模特中没有什么真正的幻想:

    public ObservableCollection<Customer> CustomerCollection { get; set; }

    private Customer _selectedCustomer;
    public Customer SelectedCustomer
    {
        get
        {
            return _selectedCustomer;
        }
        set
        {
            _selectedCustomer = value;
            OnPropertyChanged("SelectedCustomer");
        }
    }

我可以选择一个Master行,细节将适当填写。那部分效果很好。

当我编辑Detail时,我的问题出现了,它在用户点击Save之前更改了Master。如果我更改其中一个属性并且它失去焦点,则数据绑定会将主行设置为与新信息相同。我尝试了各种版本的Mode = OneWay,他们没有帮助。

如何使SelectedItem的数据绑定仅从数据网格中输出,而不是返回?当用户单击“保存”时,我将刷新数据网格,这不是问题。对我来说更重要的是,记录不会在中途改变而不是经常刷新网格。

2 个答案:

答案 0 :(得分:1)

您必须在集合的属性上设置OneTime绑定,而不是集合本身。 尝试在网格上禁用autogeneratecolumns,并使用一次性绑定自行定义列。这应该得到你需要的行为。

像这样(未经测试):

<DataGrid AutoGenerateColumns="False" ItemsSource="{Binding Customers}" SelectedItem="
     {Binding SelectedCustomer}">
    <DataGrid.Columns>
        <DataGridTextColumn Binding="{Binding Name, Mode=OneTime}" />
        <DataGridTextColumn Binding="{Binding Address, Mode=OneTime}" />
    </DataGrid.Columns>
</DataGrid>

如果你真的想要从master中分离细节,我建议你有一个单独的selectedCustomer属性,并在你完成编辑后将那个属性复制到绑定到网格的集合。一次性绑定很好,但您必须手动更新网格,如果您想使用严格的MVVM,则需要一些代码。另请注意,当您编辑详细信息时,SelectedCustomer仍将在ViewModel中更新您的集合,网格只是不会反映更改。因此,如果您点击保存,最新信息仍会写入数据库。

答案 1 :(得分:0)

您可以使用UpdateSourceTrigger 但在这种情况下,您必须以详细形式运行所有控件并手动更新源。

更复杂的解决方案是,您可以将所选行加载到详细信息表单,而不是从网格加载,而是从服务器加载。