WPF ListBox绑定未显示

问题描述:

我是WPF的新手,在将数据绑定到简单的ListBox时遇到问题.我已经在MainWindow.XAML中设置了

I'm new to WPF and am having problems binding data to a simple ListBox. I've set it up in MainWindow.XAML

<ListBox Name="lbxShows" />

然后在后面的代码中,将ItemsSource属性设置为名为ShowList的Show对象的ObservableCollection.这实际上是OasisInst是实例(在MainApplication的构造函数中设置)的另一个类(Oasis)的属性.

then in the code behind, I set the ItemsSource property to be an ObservableCollection of Show objects called ShowList. This is actually a property of another class (Oasis) of which OasisInst is an instance (setup in the constructor of MainApplication).

InitializeComponent();
mainApp = new MainApplication();
lbxShows.ItemsSource = mainApp.OasisInst.ShowList;

这时,ShowList中没有项目,但后来又添加了一些项目,而这些项目没有出现在ListBox中.

At this point, there are no items in ShowList but later, some get added and they don't appear in the ListBox.

Oasis类的代码实现INotifyPropertyChanged接口,然后具有从ShowList setter调用的教科书方法.

The code for the Oasis class implements the INotifyPropertyChanged interface and then has the textbook method that's called from the ShowList setter.

private void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
{
    if (PropertyChanged != null)
    {
        PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}

PropertyChanged是我的PropertyChangedEventHandler事件.

PropertyChanged is my PropertyChangedEventHandler event.

当我逐步进入调试模式时,PropertyChanged为null,因此似乎没有任何人订阅我的事件.鉴于通常会通过绑定自动发生这种情况(我认为呢?),那么我猜测绑定设置不正确.

When I step through in debug mode, PropertyChanged is null so it seems that nothing has subscribed to my event. Given that this would usually happen automatically through a binding (I think?), then I'm guessing the binding hasn't been setup properly.

也许仅设置ItemsSource属性不足以设置绑定?

Maybe setting the ItemsSource property alone isn't sufficient to setup the binding?

您所做的应该足以绑定ObservableCollection并让U/I接收更新. 我以为不是建议使用BindingObject,但发现它可以工作. (所以我也学到了一些东西). 这是一个简单的示例,可以与您提供的Xaml一起使用.每秒一次在列表中添加一个条目.

What you are doing should be enough to bind the ObservableCollection and have the U/I receive updates. I thought it was not so was going to suggest using a BindingObject but found it works. (So I too learned something). Here is a simple example that should work with the Xaml you provided. It adds an entry in the list once per second.

当您提到"PropertyChanged是我的PropertyChangedEventHandler事件"时,我感到困惑.请注意,唯一需要的PropertyChangedEventHandler是在Oasis对象内部.

I am confused where you mention "PropertyChanged is my PropertyChangedEventHandler event." Note that the only PropertyChangedEventHandler required is inside the Oasis object.

也许您的意思是您的U/I上还有其他控件需要在MainWindow上使用PropertyChangedEventHandler,但不应与Oasis对象内的PropertyChangedEventHandler进行交互.

Perhaps you mean you have other controls on your U/I that need a PropertyChangedEventHandler on your MainWindow but that should have no interaction with the PropertyChangedEventHandler inside the Oasis object.

----下面的代码----

---- code below ----

using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows;
using System.Windows.Threading;

namespace ListBoxTest
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    /// 

    public class OasisInstance : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        ObservableCollection<string> _items = new ObservableCollection<string>();
        public ObservableCollection<string> ShowList
        {
            get { return _items; }
            set {
                if (_items != value)
                {
                    _items = value; NotifyPropertyChanged();
                }
            }
        }

        private void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }

    public class MainApplication
    {
        public OasisInstance OasisInst  = new OasisInstance();
    }

    public partial class MainWindow : Window
    {
        MainApplication mainApp = new MainApplication();
        DispatcherTimer timer = new DispatcherTimer();

        public MainWindow()
        {
            timer.Interval = TimeSpan.FromSeconds(1);
            timer.Tick += (s, e) => { mainApp.OasisInst.ShowList.Add(DateTime.Now.ToString()); };
            timer.Start();

            InitializeComponent();

            lbxShows.ItemsSource = mainApp.OasisInst.ShowList;
        }
    }
}