WPF MasterDetail:如何在编辑Detail时保持Master不更新

本文关键字:Master 更新 Detail 编辑 MasterDetail WPF | 更新日期: 2023-09-27 18:18:04

我有一个非常直接的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行设置为与新信息相同。我试过各种版本的Mode=OneWay,但都没有用。

如何使SelectedItem的数据绑定只从数据网格中取出,而不是返回?当用户单击Save时,我将刷新数据网格,这不是问题。对我来说,记录不更改比频繁刷新网格更重要。

WPF MasterDetail:如何在编辑Detail时保持Master不更新

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

像这样(未测试):

<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>

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

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

更复杂的解决方案是,你可以加载选定的行在详细信息的形式,而不是从网格,但从服务器。