源更改时组合框 SelectedItem 不更新

Posted

技术标签:

【中文标题】源更改时组合框 SelectedItem 不更新【英文标题】:Combobox SelectedItem doesn't update when source changes 【发布时间】:2011-03-30 18:47:23 【问题描述】:

我有一个实现INotifyPropertyChanged 的视图模型。在这个 viewModel 上有一个名为 SubGroupingView 的属性。此属性绑定到组合框的选定项。当我更改组合框时,源属性更新正常,但是当我更改源属性或控件初始化时,combobox.selectedItem 不反映属性中存在的内容。 以下是一些帮助您入门的代码:

<ComboBox Grid.Column="3" Grid.Row="1" 
          Margin="0,1,4,1" 
          SelectedItem="Binding Path=SubGroupingView, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay, diag:PresentationTraceSources.TraceLevel=High" 
          ItemsSource="Binding Columns" 
          DisplayMemberPath="DisplayName">

该属性引发PropertyChanged 事件,TraceSource 输出显示绑定检测到它并传输了值,只是组合框没有反映它。任何想法都将受到欢迎!

编辑: 跟踪源的输出是这样的:

System.Windows.Data Warning: 91 : BindingExpression (hash=23631369): Got PropertyChanged event from ReportViewModel (hash=52844413)  
System.Windows.Data Warning: 97 : BindingExpression (hash=23631369): GetValue at level 0 from ReportViewModel (hash=52844413) using RuntimePropertyInfo(SubGroupingView):         DataColumnViewModel (hash=58231222)  
System.Windows.Data Warning: 76 : BindingExpression (hash=23631369): TransferValue - got raw value DataColumnViewModel (hash=58231222)  
System.Windows.Data Warning: 80 : BindingExpression (hash=23631369): TransferValue - implicit converter produced DataColumnViewModel (hash=58231222)  
System.Windows.Data Warning: 85 : BindingExpression (hash=23631369): TransferValue - using final value DataColumnViewModel (hash=58231222)  

这里是源属性的代码:

public class ReportViewModel : ViewModelBase, IReportTemplate

    public DataColumnViewModel SubGroupingView
    
        get
        
            return GetViewModel(_report.SubGrouping);
        
        set
        
            if (_report.SubGrouping == value.ColumnName)
                return;
            _report.SubGrouping = value.ColumnName;
            RefreshDataSeries();
            base.OnPropertyChanged("SubGroupingView");
            base.OnPropertyChanged("IsReady");
        

    

注意:ViewModelBase 实现 INotifyPropertyChange

回答 我重载了 ==、!= 运算符、GetHashCode()Equals(object),现在它运行良好。感谢您的所有帮助!

【问题讨论】:

出于兴趣,请尝试在 XAML 声明中的 SelectedItem 之前设置 ItemsSource。 你在跟踪我吗?运气不好 有趣...您能否发布您的 ViewModel 的 sn-p(特别是 SubGroupingView 的定义)? 如何更改源属性?它真的是列表中的对象,而不是它的任何副本吗? 由于它是一种 ViewModel 方法,因此创建了对象。我将尝试使用列表的 Columns 属性 【参考方案1】:

@CodeNaked 的答案是正确的。但在我的情况下,只是覆盖 Object.Equals 会引发 ***Exception。我认为整个答案是实现完整的 IEquatable ,这意味着实现其 Equals 方法并覆盖 Object.Equals(Object) 和 Object.GetHashCode 方法,如this example (参见“备注”部分的末尾 - “实施者须知” -和“示例”部分)。

【讨论】:

【参考方案2】:

从您的 SubGroupingView 返回的对象必须与 ComboBox.Items 中的对象之一“相等”(这意味着它必须在您的 Columns 集合中)。因此,如果您执行“a.Equals(b)”,则需要返回 true。

如果它们在功能上相同,但在比较时没有返回 true,那么这就是你的问题。您需要返回相同的对象,或者重写 Equals 方法(可能还有 == 和 != 运算符)。

如果这是您的问题,与question 中的问题相同。

【讨论】:

非常值得赏金!如果可以的话,我会进一步投票给你!这对 MVVM 有什么影响?所有 MVVM 虚拟机都应该在基类上实现比较器吗? (不能再奖励三个小时) 很难说清楚,因为每种情况都不同。如果您的 ViewModel 未在 ItemsControls 中使用,那么是否覆盖 Equals 可能无关紧要。但是如果你做一个简单的 List.Contains(something),你会遇到同样的情况。因为 Contains 也在执行相等性测试。【参考方案3】:

您的ComboBox 上的IsSynchronizedWithCurrentItem 是否可能设置为false?您可以尝试显式设置IsSynchronizedWithCurrentItem="True" 看看是否有帮助。

【讨论】:

谢谢伙计,但运气不好,如果我设置 IsSynchronizedWithCurrentItem,它不会触发源上的设置器 这在更新项目列表时帮助我,并且所选索引保持不变。 如果我设置它,我会得到“无法分配给属性 'Windows.UI.Xaml.Controls.Primitives.Selector.IsSynchronizedWithCurrentItem'。”在初始化期间(这是一个UWP应用程序,该属性是Intellisense建议的,所以它存在)

以上是关于源更改时组合框 SelectedItem 不更新的主要内容,如果未能解决你的问题,请参考以下文章

UWP 组合框绑定到 SelectedItem 属性

ItemsControl 组合框 selecteditem C# WPF MVVM

如何在通用 Windows 平台中连接组合框和图像?

更改集合时 WPF 组合框不更新

WPF C# 组合框空白 SelectedItem SelectedValue

C#ComboBox SelectedItem未更新