将列表框绑定到ObservableCollection仅适用于第一个项目



我正在尝试制作一个应用程序,将自定义对象(Places)的List/Collection等与列表框绑定,以便:

  • ListBox显示每个对象的选定属性("名称")
  • 在ListBox中选择一个项目会更改中的"当前"项目列表/集合
  • 在ListBox中添加/删除项,在中添加/移除项列表/集合
  • 在列表/集合中添加/删除项目,在中添加/移除项目列表框
  • 更改项目的显示属性,更改中的项目列表框

到目前为止,我的代码是:

namespace DataBindingTest
{
public partial class Form1 : Form
{
    BindingSource bs;
    ObservableCollection<Place> places = new ObservableCollection<Place>();
    Place place1 = new Place("pl1", 2.2);
    Place place2 = new Place("pl2", 2.3);
    public Form1()
    {
        InitializeComponent();
    }
    private void Form1_Load(object sender, EventArgs e)
    {
        bs = new BindingSource();
        places.Add(place1);
        places.Add(place2);
        bs.DataSource = places;
        listBox1.DataSource = bs;
        listBox1.DisplayMember = "Name";
        listBox1.DataBindings.Add(new Binding("Text", bs, "Name", true, DataSourceUpdateMode.OnPropertyChanged));             
    }
    public class Place : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        string name;
        double losses;
        public Place(string n, double l)
        {
            name = n;
            losses = l;
        }
        public string Name
        {
            get { return name; }
            set 
            {
                name = value;
                OnPropertyChanged("Name");
            }
        }
        public double Losses
        {
            get { return losses; }
            set { losses = value; }
        }
        protected void OnPropertyChanged(string PropertyName)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(PropertyName));
        }
    }
    private void button1_Click(object sender, EventArgs e)
    {
        places[0].Name = "Place 1";
        places[1].Name = "Place 2";
    }
}

当为places[0]调用OnPropertyChanged时,这是可以的,当为places[1]调用时,处理程序为null!为什么会发生这种情况?

解决方案

ObservableCollection似乎有问题(可能是bug?)!如果我改为使用BindingList,它可以正常工作!!在这里找到的。经过3天的搜索。

编辑

namespace DataBindingTest
{
    public partial class Form1 : Form
    {
        BindingSource bs;
        BindingList<Place> places = new BindingList<Place>();
        Place place1 = new Place("pl1", 2.2);
        Place place2 = new Place("pl2", 2.3);

        public Form1()
        {
            InitializeComponent();
        }
        private void Form1_Load(object sender, EventArgs e)
        {
            bs = new BindingSource();
            places.Add(place1);
            places.Add(place2);
            bs.DataSource = places;
            listBox1.DataSource = bs;
            listBox1.DisplayMember = "Name";
            listBox1.DataBindings.Add(new Binding("Text", bs, "Name", true, DataSourceUpdateMode.OnPropertyChanged));
            Place place3 = new Place("pl3", 0);
            bs.Add(place3);
            places[2].Name = "Place3";
        }
        private void button1_Click(object sender, EventArgs e)
        {
            places[0].Name = "Place 1";
            places[1].Name = "Place 2";
        }

    }

    public class Place : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        string name;
        double losses;
        public Place(string n, double l)
        {
            name = n;
            losses = l;
        }

        public string Name
        {
            get { return name; }
            set
            {
                name = value;
                OnPropertyChanged("Name");
            }
        }
        public double Losses
        {
            get { return losses; }
            set { losses = value; }
        }
        protected void OnPropertyChanged(string PropertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
                handler(this, new PropertyChangedEventArgs(PropertyName));
        }
    }
}

我只是把Class Place放在Class Form1之外,因为我需要在整个命名空间中使用它,但我认为它不会改变什么。

ObservableCollection似乎有问题(可能是bug?)!如果我改为使用BindingList,它可以正常工作!!在这里找到的。经过3天的搜索。

编辑

namespace DataBindingTest 
{
    public partial class Form1 : Form
    {
        BindingSource bs;
        BindingList<Place> places = new BindingList<Place>();
        Place place1 = new Place("pl1", 2.2);
        Place place2 = new Place("pl2", 2.3);

        public Form1()
        {
            InitializeComponent();
        }
        private void Form1_Load(object sender, EventArgs e)
        {
            bs = new BindingSource();
            places.Add(place1);
            places.Add(place2);
            bs.DataSource = places;
            listBox1.DataSource = bs;
            listBox1.DisplayMember = "Name";
            listBox1.DataBindings.Add(new Binding("Text", bs, "Name", true, DataSourceUpdateMode.OnPropertyChanged));
            Place place3 = new Place("pl3", 0);
            bs.Add(place3);
            places[2].Name = "Place3";
        }
        private void button1_Click(object sender, EventArgs e)
        {
            places[0].Name = "Place 1";
            places[1].Name = "Place 2";
        }

    }

    public class Place : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        string name;
        double losses;
        public Place(string n, double l)
        {
            name = n;
            losses = l;
        }

        public string Name
        {
            get { return name; }
            set
            {
                name = value;
                OnPropertyChanged("Name");
            }
        }
        public double Losses
        {
            get { return losses; }
            set { losses = value; }
        }
        protected void OnPropertyChanged(string PropertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
                handler(this, new PropertyChangedEventArgs(PropertyName));
        }
    }
}

不确定原因,但它似乎只是更新所选项目。这并不优雅,但它似乎是一个权宜之计:

private void button1_Click(object sender, EventArgs e)
{
   int actualIndex = listBox1.SelectedIndex;
   listBox1.SelectedIndex = 0;
   places[0].Name = "Place 1";
   listBox1.SelectedIndex = 1;
   places[1].Name = "Place 2";
   listBox1.SelectedIndex = actualIndex;
}

相关内容

  • 没有找到相关文章

最新更新