强制数据绑定WPF ListBox更新的更好方法是什么?

Tim*_*hyP 30 data-binding wpf listbox observablecollection

我有一个绑定到ObservableCollection的WPF ListBox,当集合发生变化时,所有项目都会更新它们的位置.

新位置存储在集合中,但UI不会更新.所以我添加了以下内容:

    void scenarioItems_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
    {
        ToolboxListItem.UpdatePositions();
        lstScenario.ItemsSource = null;
        lstScenario.ItemsSource = ToolboxListItem.ScenarioItems;
        this.lstScenario.SelectedIndex = e.NewStartingIndex;
    }
Run Code Online (Sandbox Code Playgroud)

通过将ItemsSource设置为null然后再次绑定它,UI将更新,

但这可能是非常糟糕的编码:p

建议?

Gis*_*shu 75

我有一个Listbox绑定到一个类型的对象属性,List<MyCustomType>()我验证以下代码更新列表时更新列表框.

void On_MyObjProperty_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
   MyListBox.Items.Refresh();
}
Run Code Online (Sandbox Code Playgroud)

如果您仍然遇到问题,请扫描VS IDE输出窗口(Ctrl + W,O),看看是否可以发现报告的任何绑定错误.


小智 10

WPF将列表/项集合绑定到ListBox,但UI更新后不刷新,已解决.

我只是傻瓜.虽然我已经阅读了很多关于使用ObservableCollection<>而不是使用的内容List<>,但我只是继续忽略这个建议并继续关注其他建议,但无济于事.回到我的书并重读.很好地解释了这ObservableCollection<>是必须使用的,因为当集合中的项目发生变化时,List<>不提供更新其显示INotifyCollectionChange所需的界面ListBox.

这是更新的代码:

private ObservableCollection<StringWrapper> m_AppLog;
ObservableCollection<StringWrapper> Log { get { return m_AppLog; } }
Run Code Online (Sandbox Code Playgroud)

非常简单,不需要任何其他东西(例如Refresh()).因为ObservableCollection负责触发change事件,所以我能够删除不必要的调用:

// notify bound objects
OnPropertyChanged("Log");
Run Code Online (Sandbox Code Playgroud)

ObservableCollection不支持没有创建它的线程的更新.因为我的列表(显示最近的错误/信息消息的可视日志)可以从不同的线程更新,我添加以这种方式调整我的代码,以确保更新是使用列表自己的调度程序完成的:

public void AddToLog(string message) {
    if (Thread.CurrentThread != Dispatcher.Thread) {
        // Need for invoke if called from a different thread
        Dispatcher.Invoke(
            DispatcherPriority.Normal, (ThreadStart)delegate() { AddToLog(message); });
    }
    else {
        // add this line at the top of the log
        m_AppLog.Insert(0, new StringWrapper(message));
        // ...
Run Code Online (Sandbox Code Playgroud)

另请注意,ObservableCollection<>不支持RemoveRange()相反List<>.这是从List切换到ObservableCollection时所需的可能调整的一部分.


Alf*_*son 6

我可能遇到类似的问题,但我不确定.

我有一个ObservableCollection<MyEntity>和一个ListBox绑定它.但对于一些奇怪的原因,ListBox没有被我改变的属性更新MyEntity列表中的对象.

搜索了一段时间后,我找到了以下页面,我只是想让你知道:

http://www.wblum.org/listbind/net3/index.html

这是一个非常好的描述,ListBox当列表或其中的对象发生更改时,您需要做什么来更新.希望你能从中受益.