【问题标题】:WPF MVVM ListBox/ComboBox ItemsSource won't update UI from ViewModelWPF MVVM ListBox/ComboBox ItemsSource 不会从 ViewModel 更新 UI
【发布时间】:2014-03-08 21:37:36
【问题描述】:

我有一个容器,例如列表框、组合框等,它的 ItemsSource 属性绑定到我的视图模型中的可观察集合。 当我尝试通过 VM 中的某种方法从集合中添加/删除项目时,它不会反映在 UI 中, UI 真正刷新的唯一方法是,如果我为集合分配一个新值(即具有相关数据的另一个集合),这会迫使他重新绑定整个集合。

也许我错过了/不了解有关集合绑定问题的某些内容,无论哪种方式,如果有人有解决方案/很好的解释/两者都会很棒。 这是我的视图中的一个示例(在这种情况下它是一个列表框)

<ListBox
                Grid.Row="9"
                Grid.Column="1"
                Grid.ColumnSpan="3"
                Width="200"
                Height="200"
                ItemsSource="{Binding PreSavedRecordingScheduleList,UpdateSourceTrigger=PropertyChanged}"
                SelectedItem="{Binding SelectedPreSavedRecordingSchedule,UpdateSourceTrigger=PropertyChanged}"
                DisplayMemberPath="Display"/>

这是我的 ViewModel:

private ObservableCollection<ScheduledRecordingObject> m_PreSavedRecordingScheduleList;

PreSavedRecordingScheduleList = new ObservableCollection<ScheduledRecordingObject>();

public ObservableCollection<ScheduledRecordingObject> PreSavedRecordingScheduleList
       {
            get
            {
                return m_PreSavedRecordingScheduleList;
            }
            set
            {
                m_PreSavedRecordingScheduleList = value;
                OnPropertyChanged("PreSavedRecordingScheduleList");
            }
        }

ScheduledRecordingObject 也实现了 INotifyPropertyChanged。

【问题讨论】:

  • 显示你到目前为止的代码尝试
  • 只是为了更好地理解 - 您的集合中的初始值显示在您的列表框中?
  • 是的,显示初始值。例如,我可以在 C'tor 中添加一些项目,它们将对用户可见,但我之后所做的任何更改(添加/删除/清除等)都不会刷新 UI
  • 请发布您设置数据上下文的代码,并在运行时检查数据上下文并与 snoop 绑定。

标签: wpf mvvm binding observablecollection itemssource


【解决方案1】:

视图模型

public ObservableCollection<yourType> MyItemsSource {get;set}

在构造函数中初始化一次并使用 clear、add 和 remove 来改变它

查看

 <ListBox ItemsSource="{Binding MyItemsSource}"/>

只需确保设置了正确的 DataContext。

在你的代码中应该是这样的

编辑: 对您发布的代码的一些提示:

//remove the UpdateSourceTrigger=PropertyChanged - makes no sense the Mode is OneWay anyway :)
ItemsSource="{Binding PreSavedRecordingScheduleList}"

//the following line should just called once and at best in ctor
//but the binding will of course work too when you assign a new collection
PreSavedRecordingScheduleList = new ObservableCollection<ScheduledRecordingObject>();  

所有代码看起来都不错,如果视图模型是列表框的数据上下文,那么它应该可以工作。让我知道 Snoop 正在显示什么 :)

【讨论】:

  • 谢谢我已经试过了,你说使用 clear/add/remove 来改变集合的部分不起作用。
  • 请在运行时使用 snoop 来检查您的初始绑定是否损坏。并请发布一些代码
  • 直到现在才知道有这样的工具,所以我刚刚下载了它,我要试一试。
  • 感谢模式提示,就像你说的那样,“新”行在 C'tor 中被调用一次。我会通知你的。谢谢:)
【解决方案2】:

删除 OnPropertyChanged("PreSavedRecordingScheduleList");来自 ObservableCollection。实际上,您不需要支持字段。在 ObservableCollection 上附加 CollectionChanged 事件,类似这样

1- 在 ViewModel 构造函数中附加事件 CollectionChanged

PreSavedRecordingScheduleList = new ObservableCollection<ScheduledRecordingObject>();

PreSavedRecordingScheduleList.CollectionChanged += PreSavedRecordingScheduleList_CollectionChanged;

2- 在事件处理程序中注入 OnPropertyChanged("PreSavedRecordingScheduleList")

void PreSavedRecordingScheduleList_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
    {
        OnPropertyChanged("PreSavedRecordingScheduleList");
    }

【讨论】:

    猜你喜欢
    • 2021-09-26
    • 1970-01-01
    • 1970-01-01
    • 2018-07-04
    • 2010-11-03
    • 2011-07-21
    • 1970-01-01
    • 1970-01-01
    • 2021-04-29
    相关资源
    最近更新 更多