【问题标题】:Programmatically bind an ObservableCollection to a ListBox以编程方式将 ObservableCollection 绑定到 ListBox
【发布时间】:2011-12-02 00:20:04
【问题描述】:

这个问题看起来像这样: Programmatically binding List to ListBox 但就我的例子而言,这篇文章中给出的答案对我不起作用! 无论如何,我查看了大约 10/15 个类似的帖子,但没有一个有用

这是我的 xaml 代码:

<Grid>
    <ListBox Name="ListBoxx"/>
</Grid>

这是背后的代码:

namespace WpfApplication1
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            ObservableCollection<string> MyCollection = new ObservableCollection<string>();

            Random random = new Random();
            System.Timers.Timer aTimer = new System.Timers.Timer();
            aTimer.Elapsed += (sender, e) =>
            {
                MyCollection.Add(random.Next(0, 100).ToString());
            };
            aTimer.Interval = 500;
            aTimer.Enabled = true;

            Binding myBinding2 = new Binding();
            myBinding2.Source = this;
            myBinding2.Path = new PropertyPath("MyCollection");
            ListBoxx.SetBinding(ListBox.ItemsSourceProperty, myBinding);
        }
    }
}

据我所知,我的类不必从 INotifyPropertyChanged 继承,因为我使用的是 ObservableCollection。

我不想在 xaml 代码中使用 {Binding}。

我试过这段代码:

ListBoxx.ItemsSource = MyCollection;

这“有效”,但我遇到了线程崩溃。我知道我可以使用 Dispatcher 来修复它,但它不能用我的代码修复。我想在我的代码 sn-p 中使用“真实”绑定(可配置)。

结果是我没有出错,但 ListBox 没有更新:/

我尝试添加这些行:

MyCollection.Add("aaa");
MyCollection.Add("bbb");
MyCollection.Add("ccc");
MyCollection.Add("ddd");

但我在我的应用程序中没有得到任何东西,所以我真的认为这是一个绑定问题。无论如何,我确定我的计时器没问题,问题不在这里。

我也尝试过像这样将 MyCollection 作为属性:

private ObservableCollection<string> _MyCollection = new ObservableCollection<string>();
public ObservableCollection<string> MyCollection { get { return _MyCollection; } }

但它也不起作用:/(没有错误但没有更新)

【问题讨论】:

  • 一个 WPF UI 元素从 Dispatcher 获取其数据。尝试使用 path 与 ItemsSource 不会愚弄它。为什么反对 XAML 中的绑定?最后它解析为相同的绑定。在代码中确实提供了更多的调试。您的计时器可能正在运行,但在计时器和 UI 之间的是 Dispatcher。

标签: c# wpf binding


【解决方案1】:

您发布的代码将失败,因为“MyCollection”不是 MainWindow 中的属性。您的 Visual Studio 输出窗口可能显示绑定错误。

此外,您确实需要分派您对集合所做的更改,您可以使用 DispatcherTimer 来执行此操作。输出窗口中也应该有错误。

以下代码有效:

public partial class MainWindow : Window
{
    public ObservableCollection<string> MyCollection { get; set; }

    public MainWindow()
    {
        InitializeComponent();
        MyCollection = new ObservableCollection<string>();

        Random random = new Random();
        DispatcherTimer aTimer = new DispatcherTimer();
        aTimer.Tick += (sender, e) =>
        {
            MyCollection.Add(random.Next(0, 100).ToString());
        };
        aTimer.Interval = new TimeSpan(0,0,0,0,500);
        aTimer.Start();

        Binding myBinding2 = new Binding();
        myBinding2.Source = this;
        myBinding2.Path = new PropertyPath("MyCollection");
        ListBoxx.SetBinding(ListBox.ItemsSourceProperty, myBinding2);
    }
}

【讨论】:

  • 哇,这段代码对我来说就像上帝的礼物!你定义定时器的方式是我几天来一直在寻找的......它改变了我遇到的很多麻烦,哇,太糟糕了,我不能给你更多 +1 :(
  • 我给了你一个额外的纪尧姆,因为他很高兴 :) 这对我也有帮助
【解决方案2】:

第一种情况不能作为绑定只对属性起作用。如果您创建一个如最后所示的属性,它应该可以工作,当然,绑定对象的DataContextBinding.Source 是包含该属性的对象。

您是否收到绑定错误?你试过debug it吗?

【讨论】:

  • 我不确定你所说的“错误”是什么意思,但一切似乎都很好。没有错误,没有崩溃,只是一个没有更新的空列表弓
  • 是的,我正在阅读并尝试它!我在澄清“错误”问题
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-09-18
  • 2014-09-28
  • 2012-12-16
  • 1970-01-01
  • 2018-09-11
  • 2013-12-31
  • 1970-01-01
相关资源
最近更新 更多