【问题标题】:Bound data in WPF not updatingWPF中的绑定数据不更新
【发布时间】:2013-04-02 09:34:28
【问题描述】:

我有一个显示一些 ListBox 的应用程序。这些列表框绑定到数据。其中一个列表是 Doors 列表,而另一个列表是 Users 列表。

门列表来自与数据库通信的 DataManager 类。用户列表来自另一个进行一些计算的类。

我已将这两个 ListBox 绑定到它们相应的 ObservableList getter setter。

对于门:

public ObservableList<Door> Doors
{
    get { return DataManager.Doors; }
}

对于用户来说:

public ObservableList<User> Users
{
    get { return classLogic._users; }
}

问题来了。当我添加或删除门时,UI 上的列表会更新。当我添加或删除用户时,列表不会更新。我必须重新加载视图(重新启动应用程序)才能更新它。我错过了什么?为什么它不起作用?

【问题讨论】:

    标签: c# wpf data-binding


    【解决方案1】:

    一个可观察的集合为每个项目的属性引发 PropertyChanged
    就像你有一个 IsDoorClosed 属性一样,它会更新

    删除元素会在 Doors 上引发 CollectionChanged 事件,但 UI 不会更新,因为 在 Bound Property Doors 上未引发 PropertyChanged 事件。

    您需要在 Doors 的每个 CollectionChanged 上引发 PropertyChanged 事件。

    类似于以下内容:这是 psado 代码,它是作为示例写在这里的 为了您的利益,请检查是否有任何语法错误。

     Doors.CollectionChanged += OnDoorsCollectionChanged; 
    
    
     private static void OnDoorsCollectionChanged(object sender , CollectionChangedEventArgs e)
     {
          PropertyChanged(sender,new PropertyChangedEventArgs("Doors"));
     }
    

    【讨论】:

    • 好的,我添加了一个示例,我不知道您的收藏在哪里,但是您需要在 DataContext 中的“Doors”属性上提高 PropertyChanged。另请注意,我是在此处而不是在 VS 中编写的,因此请考虑语法错误。
    • 好吧,但有趣的是,我没有在 User 类上这样做。尽管如此,用户的 ListBox 仍会更新。这怎么可能?
    • 您能否发布 classLogic._users 和 DataManager.Doors 的 CS 以进行比较,我想我大概知道为什么会发生这种情况
    • CS?你那是什么意思?我只是使用 lists.Add() 方法...请注意 Doors 可以工作,但用户不能。你有相反的方式:)
    • 好吧,我的错误,无论哪种方式,我都想看看集合是如何定义的。
    【解决方案2】:

    我发现自己需要完成三个步骤。我认为更新 ListBox 不需要 PropertyChanged 事件。这可能是从 .NET 4.0 开始,因为我在下面的版本中阅读过,数据绑定还不是真正正确的。

    第一步是列表必须是private static ObservableList&lt;...&gt;。第二个是这个列表的 getter 也必须是适当的类型。这意味着在我的情况下,以下代码需要在 ClassLogic 中:

    private static readonly ObservableList<User> _users= new ObservableList<User>();
    
    public static ObservableList<User> Users
    {
        get { return _users; }
    }
    

    第三件事是,当在DataContext类中调用这个函数(getter)将数据绑定到ListBox时,必须使用类名而不是该类的实例!

    所以,在这种情况下应该是:

    /// <summary>
    /// Gets the Users that are managed by the ClassLogic class
    /// </summary>
    public ObservableList<User> Users
    {
        get { return ClassLogic.Users; }
        //wrong would be:
        //get { return classLogic.Users }
    }
    

    这 3 个步骤绑定了我的数据,并确保在更新列表内容时更新 ListBox。

    【讨论】:

    • 很好,我想知道在什么情况下集合属性上需要 PropertyChanged 事件我记得需要它的情况。
    • 我的想法完全正确。也许当列表从一开始就不可观察时?我想到了外部应用程序或更新不是列表而是图像的东西......
    • 更新列表时更改 ObservableCollection 与更改集合中存储的项目之间存在差异。如果集合内的项目发生更改,则可以使用 INotifyPropertyChanged。来自:stackoverflow.com/questions/9469056/…
    猜你喜欢
    • 2023-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多