编程语言
首页 > 编程语言> > c# – WPF MVVM可观察集合不更新GUI

c# – WPF MVVM可观察集合不更新GUI

作者:互联网

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

为此,我在ViewModel上创建了一个名为CustomerSummaryDetails的独立属性,它只包含一个get,它返回我上面提到的客户中包含的集合.

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

这是因为我没有必须绑定到SelectedCustomer.SummaryDetails,这不是那么干净.

SelectedCustomer属性具有get和set方法,set为OTHER属性CustomerSummaryDetails调用OnPropertyChanged,让XAML知道底层集合已更改并更新.

问题是,当我更新集合中的项目时,尽管调用了所有正确的事件,但它并没有反映在GUI上.我已经介入并调用了SelectedCustomer的set方法,然后我按照OnPropertyChanged(“CustomerSummaryDetails”)调用进入CustomerSummaryDetails属性的“get”方法,如预期的那样.我已经深入研究了返回集合的值,并且列表中的值是更新后的值,但是没有任何内容反映在GUI上,所以我很困惑,因为看起来GUI正在调用get方法来更新它在OnPropertyChanged()调用上,但它没有在视觉上反映.

更新 – 包含的代码

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

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方法进行实际更新

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本身(例如添加/删除项目),而是修改INSIDE集合中的项目. ObservableCollection负责通知自己的更改,而不是与其项目相关的更改.您应该在SubCustValue的setter中NotifyPropertyChange(“SubCustValue”).

UI中没有反映更改,因为当NotifyPropertyChange()整个集合而不是单个项目的单独属性时,WPF检测到它实际上是与以前相同的实例(与同一集合相同的对象引用),所以似乎没有任何改变.

标签:c,mvvm,wpf,observablecollection
来源: https://codeday.me/bug/20190713/1446958.html