【问题标题】:Why does Combobox binding not work with List<T>为什么 Combobox 绑定不适用于 List<T>
【发布时间】:2011-10-19 21:52:27
【问题描述】:

我正在尝试像这样在 WPF 中绑定一个组合框,

<ComboBox Width="350" Margin="5" IsEditable="True" ItemsSource="{Binding ComboboxItems}" DisplayMemberPath="Name">

public List<ExpandoObject> ComboboxItems
{
    get
    {
        return comboboxItems;
    }
}

如果我在我的视图模型中设置这样的列表,

comboboxItems.Clear();

foreach (ExpandoObject comboboxItem in repository.LoadComboboxItems())
{
    comboboxItems.Add(comboboxItem);
}

NotifyPropertyChanged(this, x => x.ComboboxItems);

NotifyPropertyChanged 似乎工作,因为 ComboboxItems 上的断点被命中,但随后组合框列表不会在 GUI 上更新。 Snoop 没有显示绑定错误或类似情况。

上面的列表第一次更新时似乎可以工作,所以我认为它与使用 ExpandoObject 没有任何关系。

更新:

使用可观察集合有效,但我想知道我是否在这样的视图模型中有一个设置器,它绑定到 GUI 上的控件,

public string Database
{
    get
    {
        return importData.Database;
    }
    set
    {
        importData.Database = value;
        NotifyPropertyChanged(this, x => x.Database);

        comboboxItems.Clear();

        foreach (ExpandoObject comboboxItem in repository.LoadComboboxItems())
        {
            comboboxItems.Add(comboboxItem);
        }

        NotifyPropertyChanged(this, x => x.ComboboxItems);
   }
}

该设置器是否在后台线程上运行?我问的原因是如果从数据库加载项目需要一段时间,setter 会阻止 GUI 吗?

这是我第一次尝试使用 ObservableCollection 时出错的地方,方法是使用 BackgroundWorker 在后台线程上运行 setter 中的代码。在这些情况下更新 ObservableCollection 会导致异常。

【问题讨论】:

标签: c# wpf


【解决方案1】:

我认为如果您使用 ObservableCollection 而不是 List,它会起作用。除非您使用 ObservableCollection,否则 xaml 不会知道列表的内容发生了变化。

要回答问题的第二部分,如果您尝试直接使用 BackgroundWorker 设置 ObservableCollection,您将收到异常。绕过异常的一种方法是使用 BeginInvoke 设置 ObservableCollection

需要注意的一点:您不需要在 setter 中调用 NotifyPropertyChanged(this, x =&gt; x.ComboboxItems);。这是因为属性没有改变;该属性是一个集合,集合 contents 正在发生变化。 ObservableCollection 将通知订阅者内容已更改。

【讨论】:

  • 嗯。我认为你在那里是赢家。我在使用 Observable 集合时遇到了一些其他问题,但请查看更新,因为我已经纠正了大部分问题。
【解决方案2】:

使用ObservableCollection 而不是列表。

引用 MSDN:

您可以枚举任何实现 IEnumerable 的集合 界面。但是,要设置动态绑定,以便插入或 集合中的删除会自动更新 UI, 集合必须实现 INotifyCollectionChanged 接口。这 接口暴露了 CollectionChanged 事件,该事件应该是 每当基础集合发生变化时引发。

WPF 提供了 ObservableCollection 类,它是一个内置的 实施数据收集,实施 INotifyCollectionChanged 接口。

在实现您自己的集合之前,请考虑使用 ObservableCollection 或现有集合类之一, 例如 List、Collection 和 BindingList 等等。 如果您有一个高级场景并想实现自己的 集合,考虑使用 IList,它提供了一个非泛型 可以通过索引单独访问的对象集合。 实现 IList 提供了数据绑定的最佳性能 引擎。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-04
    • 1970-01-01
    • 1970-01-01
    • 2018-11-03
    相关资源
    最近更新 更多