【问题标题】:Combobox SelectedItem doesn't update when source changes源更改时组合框 SelectedItem 不更新
【发布时间】: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 属性

标签: wpf mvvm binding combobox selecteditem


【解决方案1】:

@CodeNaked 的答案是正确的。但在我的情况下,只是覆盖 Object.Equals 会引发 StackOverflowException。我认为整个答案是实现完整的 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建议的,所以它存在)
    猜你喜欢
    • 2021-07-23
    • 1970-01-01
    • 1970-01-01
    • 2013-11-03
    • 2021-05-03
    • 1970-01-01
    • 1970-01-01
    • 2011-08-17
    • 1970-01-01
    相关资源
    最近更新 更多