【问题标题】:how to update listbox items with INotifyPropertyChanged如何使用 INotifyPropertyChanged 更新列表框项目
【发布时间】:2009-03-12 14:29:16
【问题描述】:

我有一个列表框,它数据绑定到一组对象。 我想修改项目的显示方式,以向用户显示这些对象中的哪一个是我程序中的 START 对象。

我尝试通过以下方式执行此操作,但列表框不会自动更新。 使控件无效也不起作用。

我能找到的唯一方法是完全删除数据绑定并重新添加。但就我而言,这是不可取的。

还有其他方法吗?

class Person : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    private string _name;
    public string Name
    {
        get
        {
            if (PersonManager.Instance.StartPerson == this)
                return _name + " (Start)";                      
            return _name;
        }
        set
        {
            _name = value;
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs("Name"));
        }
    }

    public Person(string name)
    {
        Name = name;
    }
}

这是管理列表和开始项目的类

class PersonManager
{
    public BindingList<Person> persons { get; set; }
    public Person StartPerson { get; set; }

    private static PersonManager _instance;
    public static PersonManager Instance
    {
        get
        {
            if (_instance == null)
            {
                _instance = new PersonManager();
            }
            return _instance;
        }
    }

    private PersonManager()
    {
        persons = new BindingList<Person>();
    }
}

在表单中我使用以下代码

    private void button1_Click(object sender, EventArgs e)
    {
        PersonManager.Instance.StartPerson = (Person)listBox1.SelectedItem;
    }

【问题讨论】:

    标签: c# winforms data-binding inotifypropertychanged


    【解决方案1】:

    我很确定问题在于,当你这样做时,你实际上是在让 Person.Name 属性“get”访问器更改值(并且就 UI 而言就像一个 set 访问器)。

    但是,没有任何更新绑定来说明这种情况正在发生。如果在您设置开始时调用了 PropertyChanged,我相信这会更新。

    它很笨重,但是你写它的方式,我相信你可以添加它并让它工作(注意:我没有测试这个,所以它〜可能〜有问题):

    private void button1_Click(object sender, EventArgs e)
    {
        Person newStart = (Person)listBox1.SelectedItem;
        if (newStart != null)
        {
            PersonManager.Instance.StartPerson = newStart;
            newStart.Name = newStart.Name; // Dumb, but forces a PropertyChanged event so the binding updates
        }
    }
    

    【讨论】:

    • 非常感谢您的快速响应,这就像一个魅力!
    • 只是好奇,如果您从头开始编写这样的代码,您将如何解决这个问题?
    • 一种可能更简洁的方法可能是拥有类似 Name + DisplayName 属性的东西。或者,如果您有一个属性来确定一个人是否是“开始”人,那么设置它会引发事件。有很多选择 - 这实际上取决于它的使用方式。
    • 在我的实际代码中,我有 2 个属性(Name + NameInclStart)。我现在有一个工作示例,但不幸的是我的实际代码不起作用(使用完全相同的逻辑):S。无论如何,我这样设置的原因是项目本身负责正确显示自己。
    • 只要确保,当您更改任一属性(尤其是 NameInclStart)时,您将触发 PropertyChanged 事件。我建议添加第三个,仅获取属性 (DisplayName),并在设置 Name OR NameInclStart 时调用 NotifyChanged(..., "DisplayName")。这将“修复”它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-06-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多