源更改时组合框 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您的ComboBox
上的IsSynchronizedWithCurrentItem
是否可能设置为false
?您可以尝试显式设置IsSynchronizedWithCurrentItem="True"
看看是否有帮助。
【讨论】:
谢谢伙计,但运气不好,如果我设置 IsSynchronizedWithCurrentItem,它不会触发源上的设置器 这在更新项目列表时帮助我,并且所选索引保持不变。 如果我设置它,我会得到“无法分配给属性 'Windows.UI.Xaml.Controls.Primitives.Selector.IsSynchronizedWithCurrentItem'。”在初始化期间(这是一个UWP应用程序,该属性是Intellisense建议的,所以它存在)以上是关于源更改时组合框 SelectedItem 不更新的主要内容,如果未能解决你的问题,请参考以下文章
ItemsControl 组合框 selecteditem C# WPF MVVM