当源更改时,组合框 SelectedItem 不会更新
我有一个实现 INotifyPropertyChanged 的视图模型。此 viewModel 上有一个名为 SubGroupingView
的属性。该属性绑定到组合框的选定项目。当我更改组合框时,源属性会很好地更新,但是当我更改源属性或初始化控件时,combobox.selectedItem
不反映属性中存在的内容。< br> 下面是一些可以帮助您入门的代码:
<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)
,现在它运行良好。感谢您的帮助!
I have a viewmodel which implement INotifyPropertyChanged
. On this viewModel is a property called SubGroupingView
. This property is bound to the selected item of a combo box. When i change the combo box, the source property is being updated fine, but when I change the source property or when the control is initialized, the combobox.selectedItem
is NOT reflecting what exists in the property.
Here is some code to get you started:
<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">
The property raises the PropertyChanged
event and the TraceSource output shows me that the binding detected it and transferred the value, its just that the combobox isn't reflecting it. Any ideas would be most welcome!
EDIT:
output from the trace source is this:
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)
Here is the code for the source property:
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");
}
}
}
Note: ViewModelBase
implements INotifyPropertyChange
.
ANSWER
I overloaded the ==, != operators, GetHashCode()
, and Equals(object)
and now it is working nicely. Thanks for all of your help!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
从 SubGroupingView 返回的对象必须“等于”ComboBox.Items 中的对象之一(这意味着它必须位于 Columns 集合中)。因此,如果您执行“a.Equals(b)”,则需要返回 true。
如果它们在功能上相同,但比较时不返回 true,那么这就是您的问题。您需要返回相同的对象,或者重写 Equals 方法(以及可能的 == 和 != 运算符)。
如果这是您的问题,则与此问题中的问题相同。
The object returned from your SubGroupingView must be "equal" to one of the objects in the ComboBox.Items (which means it must be in your Columns collection). So if you perform an "a.Equals(b)", it would need to return true.
If they are functionally the same, but not returning true when compared then that's your problem. You would need to either return the same object, or override the Equals method (and potentially the == and != operators).
If this is your issue, it's the same problem as in this question.
您的 ComboBox 上的 IsSynchronizedWithCurrentItem 是否设置为 false?您可以尝试显式设置
IsSynchronizedWithCurrentItem="True"
并查看是否有帮助。Is
IsSynchronizedWithCurrentItem
on yourComboBox
perhaps set tofalse
? You could try explicitly settingIsSynchronizedWithCurrentItem="True"
and see if that helps.@CodeNaked 的答案是正确的。但就我而言,仅重写 Object.Equals 就会引发 StackOverflowException。我认为整个答案是实现完整的 IEquatable,这意味着实现其 Equals 方法并重写 Object.Equals(Object) 和 Object.GetHashCode 方法,如 此示例(请参阅“备注”部分的末尾 - “实施者注意事项” - 和“示例”部分)。
The @CodeNaked 's answer is right. But in my case just overriding Object.Equals throws StackOverflowException. I think the whole answer is to implement full IEquatable that means implementing its Equals method and overriding Object.Equals(Object) and Object.GetHashCode methods as in this example (see the end of "Remarks" section - "Notes to Implementers" - and "Examples" section).
根据我的经验,您需要通过从 ItemsSource 搜索来设置 SelectedItem。
对于 MVCC 示例,如果您创建了一个组合框,
请注意:“item_name”是 Items 集合中 item 元素的属性。
那么你设置
暂时就可以了,但是如果你想改变SelectedItem,你就不能设置
这不会改变UI上的SelectedItem。
相反,您必须通过从 Items 集合中搜索项目来设置 OneItem
希望这对某人有帮助。
As my experience, You need set the SelectedItem by searching from ItemsSource.
For MVCC example, If you created a combobox with
Note that: "item_name" is a property of item element in Items collection.
Then you set
It's okay for now, But if you want to change the SelectedItem, you cannot set
This will not change the SelectedItem on UI.
Instead, you must set the OneItem by searching for item from Items collection
Hope this help someone.