WPF Master\Detail:编辑细节时如何保持主人的更新? [英] WPF Master\Detail: How to keep Master from updating when Detail is edited?

查看:231
本文介绍了WPF Master\Detail:编辑细节时如何保持主人的更新?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



XAML代码段:




 < Grid Grid.Row =0Grid.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 =0Grid.Column =0/>
< Label Content ={Binding SelectedCustomer.CustId}Grid.Row =0Grid.Column =1/>

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

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

< / Grid>

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

模型中没有什么真正的想法:

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

私人客户_selectedCustomer;
public Customer SelectedCustomer
{
get
{
return _selectedCustomer;
}
set
{
_selectedCustomer = value;
OnPropertyChanged(SelectedCustomer);
}
}

我可以选择一个主行,细节将填写在适当的



当我编辑细节时,我的问题来了,它在用户点击保存之前更改了Master。如果我更改其中一个属性,并放弃焦点,数据绑定将使主行与新信息相同。我已经尝试过各种版本的Mode = OneWay,他们没有帮助。



如何使SelectedItem的数据绑定仅从datagrid出来,而不是返回?当用户单击保存时,我将刷新datagrid,这不是问题。对我来说更重要的是,记录不会太频繁地刷新网格。

解决方案

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



这样的东西(未测试):

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

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


I have a pretty straight-forward MVVM Master\Detail window -

XAML snippet:

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

Nothing really fancy in the Model:

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

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

I can select a Master row and the detail will fill in appropriately. That part works great.

My problem comes when I edit the Detail, it changes the Master before the user hits Save. If I change one of the properties and it looses focus the databinding will set the Master row to be the same as the new information. I have tried various versions of Mode=OneWay and they don't help.

How do I make the databinding for the SelectedItem only go from the datagrid out, not back in? I will refresh the datagrid when the user clicks Save, that's not an issue. It's more important to me that the record not change mid-stream than to refresh the grid too often.

解决方案

You have to set the OneTime binding on the properties of the collection, not the collection itself. Try disabling autogeneratecolumns on your grid and define the columns yourself with a onetime binding. That should get the behavior you need.

Something like this (not tested):

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

If you really want to separate detail from master though, i recommend having a separate selectedCustomer property and copy that one to the collection bound to the grid when you are done editing. The onetime binding is nice, but you have to update your grid manually, which takes a bit of code if you want to work with strict MVVM. Also note that when you edit the detail, the SelectedCustomer will still be updated on your collection in the ViewModel, the grid just won't reflect the changes yet. So if you hit save the latest information would still be written to the DB.

这篇关于WPF Master\Detail:编辑细节时如何保持主人的更新?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆