WPF数据网格绑定在单击行标题之前不会更新

Bob*_*orn 13 wpf binding datagrid

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

这是XAML中的datagrid:

<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>
Run Code Online (Sandbox Code Playgroud)

这是来自视图模型:

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

    set
    {
        this._transactionDetailList = value;
        RaisePropertyChanged("TransactionDetailList");                
    }
}
Run Code Online (Sandbox Code Playgroud)

这是视图模型中其中一个项目的编辑:

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

    MainWindowViewModel.ViewLoader.ShowDialog(viewModel);

    if (viewModel.TransactionDetail != null)
    {
        this.TransactionDetailList.Add(viewModel.TransactionDetail);
        RaisePropertyChanged("TransactionDetailList");
    }
}
Run Code Online (Sandbox Code Playgroud)

运行之后,我可以在TransactionDetailList的getter上放置一个断点,并且该集合中包含该项.但是,datagrid是空的.如果我单击标题行,该项目将显示在网格中.

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

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

我刚注意到一些有趣的东西 当我单击网格标题时,TransactionDetailList getter中的断点不会被点击,但数据仍会显示.因此,它就像网格有信息一样,只是在点击标题之后才会显示它.

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

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

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

    RaisePropertyChanged("TransactionDetailList");
}
Run Code Online (Sandbox Code Playgroud)

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

Mer*_*ham 10

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

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

尝试使用ObservableCollection<TransactionDetail>而不是List<TransactionDetail>. ObservableCollection<T>内置并实现INotifyCollectionChanged,因此您不必为代码做太多工作.

还要确保INotifyPropertyChanged您已经在视图模型上继续实施.这样,当您替换整​​个集合时(通知调用setter时)将通知视图.

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

    set
    {
        this._transactionDetailList = value;
        RaisePropertyChanged("TransactionDetailList");                
    }
}
Run Code Online (Sandbox Code Playgroud)

看到:

编辑:

此外,应实现INotifyPropertyChangedTransactionDetail了.如果你不能,将它包装在一个实现的类中INotifyPropertyChanged.

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

如果您尝试通过调用RaisePropertyChangedlist属性来解决此问题,那么您的UI会认为需要抛出并更新整个列表(以及整个UI对象集).这会扼杀你的表现并让你的应用程序变得迟钝.