WPF MVVM可观察的集合不更新GUI [英] WPF MVVM observable collection not updating GUI

查看:77
本文介绍了WPF MVVM可观察的集合不更新GUI的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在设计一个MVVM WPF应用程序,并具有一个ViewModel,该ViewModel具有一个名为SelectedCustomer的,类型为Customer的属性.该对象具有一个名为ObservableCollection类型的SummaryDetails属性,该属性逐行呈现到ListView中.

Im designing an MVVM WPF app, and have a ViewModel which has a property called SelectedCustomer, of type Customer. This object has a property called SummaryDetails of type ObservableCollection which renders into a ListView, line by line.

为此,我在ViewModel上创建了一个名为CustomerSummaryDetails的单独属性,该属性仅包含一个get,该属性返回上述客户中包含的集合.

To do this, I have created a separate property on the ViewModel called CustomerSummaryDetails which contains simply a get, that returns the collection contained within the customer I mentioned above.

在XAML中,我已将ItemsSource绑定到CustomerSummaryDetails属性.

In the XAML I have bound the ItemsSource to the CustomerSummaryDetails Property.

是这样,所以我不必绑定到不太干净的SelectedCustomer.SummaryDetails.

This was so I didnt have to bind to SelectedCustomer.SummaryDetails which isn't as clean.

SelectedCustomer属性具有get和set方法,并且该集合为OTHER属性CustomerSummaryDetails调用OnPropertyChanged,让XAML知道基础集合已更改并进行更新.

The SelectedCustomer property has a get and a set method, and the set calls OnPropertyChanged for the OTHER property, CustomerSummaryDetails, letting the XAML know that the underlying collection has changed and to update.

问题在于,尽管我更新了集合中的项目,但尽管调用了所有正确的事件,但它仍未反映在GUI上.我已介入,并调用了SelectedCustomer的set方法,然后按照预期的那样,执行了OnPropertyChanged("CustomerSummaryDetails")调用,该调用进入到CustomerSummaryDetails属性的"get"方法中.此时,我已经深入研究了返回的集合的值,列表中的值是更新后的值,但是GUI上没有反映任何内容,所以我很困惑,因为似乎GUI正在调用get方法来更新它在OnPropertyChanged()调用中显示,但并没有在视觉上反映出来.

The problem is though that when I update an item within the collection, it is not reflecting on the GUI, despite all the right events being called. I have stepped in and the set method of the SelectedCustomer is being called, and I then follow the OnPropertyChanged("CustomerSummaryDetails") call which goes into the "get" method of the CustomerSummaryDetails property as expected. I have delved into the value of the returned collection at this point, and the value within the list is the updated value, however nothing is getting reflected on the GUI, so I am puzzled as it seems the GUI is calling the get method to update it on the OnPropertyChanged() call, but it is not reflecting visually.

更新-包含代码

很抱歉不包含代码,我认为只描述一下会更容易,但这是ViewModel的主要属性

Sorry for not including code, I thought it would be easier to just describe but here are the main ViewModel properties

public CustomerSummaryViewModel SelectedCustomer
{
    get { return _selectedCustomer; }
    set
    {
        _selectedCustomer = value;
        OnPropertyChanged("CustomerSummaryDetails");
    }
}

public ObservableCollection<RbcUICustomerSummary> CustomerSummaryDetails
{
    get { return _selectedCustomer.SummaryDetails; }
}

public ItemSummaryViewModel SelectedItem
{
    get { return _selectedItem; }
    set
    {
        _selectedItem = value;
        OnPropertyChanged("SelectedItem");
    }
}

下面的XAML

    <ListView x:Name="lvCustomerSummary" Margin="10,10,10,10" Background="#F4F8FB" ItemsSource="{Binding CustomerSummaryDetails}" MouseDoubleClick="lvCustomerSummary_MouseDoubleClick" ItemContainerStyle="{StaticResource myHeaderStyleColor}" VirtualizingStackPanel.IsVirtualizing="False" VirtualizingStackPanel.VirtualizationMode="Recycling">
            <ListView.View>
            <GridView ColumnHeaderContainerStyle="{StaticResource myHeaderStyle}">
                    <GridView.Columns>
                    <GridViewColumn Header=""  >
                        <GridViewColumn.CellTemplate>
                            <DataTemplate >
                                <Grid>
                                    <Image Source="{z:ImageStaticResource {Binding IconSelect}}" Width="20" Height="20" />
                                </Grid>
                            </DataTemplate>
                        </GridViewColumn.CellTemplate>
                    </GridViewColumn>
                    <GridViewColumn Width="200" Header="SubCustType" DisplayMemberBinding="{Binding SubCustType}" >
                    </GridViewColumn>
                    <GridViewColumn Width="200" Header="SubCustValue"  DisplayMemberBinding="{Binding SubCustValue}">
                    </GridViewColumn>
                    <GridViewColumn Header=""  >
                        <GridViewColumn.CellTemplate>
                            <DataTemplate >
                                <Grid>
                                    <Image Source="{z:ImageStaticResource {Binding IconFlag}}" Width="20" Height="20" />
                                </Grid>
                            </DataTemplate>
                        </GridViewColumn.CellTemplate>
                    </GridViewColumn>
                </GridView.Columns>
            </GridView>
        </ListView.View>
    </ListView>

最后是执行实际更新的Updater方法

And finally the Updater method which does the actual update

private void DisplayCustomerComment(string commentEnt)
{            
    if (_queueViewModel.SelectedCustomer == null) return;
        var selCust = _queueViewModel.SelectedCustomer;

    foreach (var t in selCust.SummaryDetails
        .Where(t => t.SubCustType == AppString.CustomerSummary.Comment))
    {
        t.SubCustValue = commentEnt;
        break;
    }

    _queueViewModel.SelectedCustomer = selCust;
}

推荐答案

您不是要修改ObservableCollection本身(例如添加/删除项目),而是修改该集合中的项目. ObservableCollection负责通知自己的更改,而不是与其项目相关的更改.您应该在SubCustValue的设置器中使用NotifyPropertyChange("SubCustValue").

You're not modifying the ObservableCollection itself (such as adding/removing items) but the items INSIDE that collection. The ObservableCollection is responsible for notifying its own changes, not changes pertaining to its items. You Should NotifyPropertyChange("SubCustValue") in the setter of your SubCustValue.

更改未反映在UI中,因为当您使用NotifyPropertyChange()整个集合时,WPF会检测到它实际上是同一实例(对同一集合的同一对象引用),而不是单个项目的单个属性.和以前一样,所以似乎什么都没有改变.

The change is not being reflected in the UI because when you NotifyPropertyChange() the entire collection, instead of the indiviual property of the individual item, WPF detects it is actually the same instance (the same object reference to the same collection) as before, so nothing seems to have changed.

这篇关于WPF MVVM可观察的集合不更新GUI的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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