WPF 数据网格绑定在单击行标题之前不会更新 [英] WPF Datagrid Binding Doesn't Update Until Clicking Row Header

查看:19
本文介绍了WPF 数据网格绑定在单击行标题之前不会更新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个绑定到视图模型中的列表的数据网格.在我单击行标题之前,网格的内容不会更新.单击各种单元格不会影响它.我必须点击标题.

I have a datagrid that is bound to a List in the view model. The grid's contents don't update until I click on the row header. Clicking in various cells doesn't affect it. I have to click on the header.

这是 XAML 中的数据网格:

This is the datagrid in the XAML:

<DataGrid x:Name="TransactionDetailsGrid" Grid.Row="1" AutoGenerateColumns="False" SelectionMode="Extended" IsReadOnly="True" HeadersVisibility="Column"
                  ItemsSource="{Binding TransactionDetailList}" SelectedItem="{Binding SelectedTransactionDetail}" GridLinesVisibility="None">
    <DataGrid.Columns>
        <DataGridTextColumn Binding="{Binding Path=Account.AccountNumber}" Header="Account No." HeaderStyle="{StaticResource DataGridHeaderStyleCenter}" Width="120" />
        <DataGridTextColumn Binding="{Binding Path=Account.AccountName}" Header="Account Name" HeaderStyle="{StaticResource DataGridHeaderStyleCenter}" Width="*" />
        <DataGridTextColumn Binding="{Binding Path=Amount}"  Header="Amount" HeaderStyle="{StaticResource DataGridHeaderStyleCenter}" Width="120" />
    </DataGrid.Columns>
</DataGrid>

这是来自视图模型:

public List<TransactionDetail> TransactionDetailList
{
    get { return this._transactionDetailList; }

    set
    {
        this._transactionDetailList = value;
        RaisePropertyChanged("TransactionDetailList");                
    }
}

这是对视图模型中的一项的

This is the edit of one of the items, in the view model:

private void AddTransactionDetail()
{
    TransactionDetailViewModel viewModel = new TransactionDetailViewModel();

    MainWindowViewModel.ViewLoader.ShowDialog(viewModel);

    if (viewModel.TransactionDetail != null)
    {
        this.TransactionDetailList.Add(viewModel.TransactionDetail);
        RaisePropertyChanged("TransactionDetailList");
    }
}

这个运行后,我可以在 TransactionDetailList 的 getter 上设置一个断点,并且集合中有项目.但是,数据网格是空的.如果我点击标题行,该项目会显示在网格中.

After this runs, I can put a breakpoint on the getter of TransactionDetailList, and the collection has the item in it. However, the datagrid is empty. If I click on the header row, the item shows up in the grid.

我在编辑时遇到了同样的问题.

I have the same issue when doing an edit.

我以前成功地做到了这一点,所以我不确定这里有什么不同.我错过了一些明显的东西吗?为什么在我点击标题行之前网格不会显示其内容?

I've done this successfully before, so I'm not sure what's different here. Am I missing something obvious? Why won't the grid show its contents until I click on the header row?

我刚刚注意到一些有趣的事情.当我点击网格标题时,TransactionDetailList getter 中的断点没有被命中,但数据仍然显示.所以,就像网格有信息一样,它只是在点击标题之前不显示.

I just noticed something interesting. When I click on the grid header, the breakpoint in the TransactionDetailList getter doesn't get hit, but the data still shows up. So, it's like the grid has the info, it's just not showing it until the header is clicked.

改为使用 ObservableCollection 后,它起作用了.但是现在我在编辑时遇到了同样的问题(网格在单击标题之前不会更新):

After changing to use ObservableCollection, it worked. But now I'm having the same problem with the edit (grid doesn't update until clicking the header):

private void EditTransactionDetail()
{
    TransactionDetailViewModel viewModel = new TransactionDetailViewModel(this.SelectedTransactionDetail);

    MainWindowViewModel.ViewLoader.ShowDialog(new TransactionDetailViewModel(this.SelectedTransactionDetail));

    RaisePropertyChanged("TransactionDetailList");
}

我的实体是否需要实现 INotifyPropertyChanged?如果我更改集合并调用 RaisePropertyChanged,这是否会导致网格更新?

Does my entity need to implement INotifyPropertyChanged? If I change the collection, and call RaisePropertyChanged, shouldn't that cause an update to the grid?

推荐答案

问题在于,当您从集合中添加或删除项目时,不会调用 setter.这意味着 INotifyPropertyChanged 没有被调用,并且视图无法知道它需要刷新.

The problem is that when you add or remove an item from the collection, the setter isn't called. This means INotifyPropertyChanged isn't called, and the view has no way of knowing it needs to be refreshed.

WPF 通过还支持 INotifyCollectionChanged 接口解决了这个问题.

WPF solves this by also supporting the INotifyCollectionChanged interface.

尝试使用 ObservableCollection 而不是 List.ObservableCollection 是内置的,并实现了 INotifyCollectionChanged,因此您无需对代码做太多工作.

Try using an ObservableCollection<TransactionDetail> instead of a List<TransactionDetail>. ObservableCollection<T> is built in, and implements INotifyCollectionChanged, so you won't have to do much to your code.

还要确保您继续在您的视图模型上实现 INotifyPropertyChanged,就像您已经拥有的那样.这样,当您替换整​​个集合时(调用 setter 时),视图会收到通知.

Also make sure that you continue to implement INotifyPropertyChanged on your view model as you already have. This way the view will be notified when you replace the entire collection (when the setter is called).

public ObservableCollection<TransactionDetail> TransactionDetailList
{
    get { return this._transactionDetailList; }

    set
    {
        this._transactionDetailList = value;
        RaisePropertyChanged("TransactionDetailList");                
    }
}

见:

  • http://msdn.microsoft.com/en-us/library/ms668604.aspx
  • http://msdn.microsoft.com/en-us/library/ms748365.aspx (although this isn't using MVVM style)

编辑:

此外,您还应该在 TransactionDetail 上实现 INotifyPropertyChanged.如果不能,请将其包装在实现 INotifyPropertyChanged 的类中.

Also, you should implement INotifyPropertyChanged on TransactionDetail too. If you can't, wrap it in a class that does implement INotifyPropertyChanged.

如果您不在 TransactionDetail 上实现它,那么您所做的更改不会影响列表,但会影响 TransactionDetail 实例上的属性,不会直到您以某种方式刷新整个列表后才显示在 UI 中.

If you don't implement it on TransactionDetail, than changes you make that don't impact the list, but do impact properties on a TransactionDetail instance, won't show in the UI until you somehow refresh the whole list.

如果您尝试通过在列表属性上调用 RaisePropertyChanged 来解决此问题,那么您的 UI 认为整个列表(以及整个 UI 对象集)需要被丢弃和更新.这会降低您的性能并使您的应用运行缓慢.

If you tried to fix this by calling RaisePropertyChanged on the list property, then your UI thinks the entire list (and hence the whole set of UI objects) needs to be thrown out and updated. This will kill your performance and make your app sluggish.

这篇关于WPF 数据网格绑定在单击行标题之前不会更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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