项源绑定不更新值

本文关键字:更新 绑定 | 更新日期: 2023-09-27 18:36:02

我需要列出项目。我将用户集合绑定到列表框。一切正常,但列表框中的项目不会实时更新。此绑定根本不会更新它们。因此,当我从列表中删除任何用户时,即使其源已正确更改,列表框也不会更新。

源位于路径 DataViewModel.Instance.AllUsers 的数据视图模型中;每当我向此列表中添加新项目或删除项目时,布局都不会更新。其他绑定效果很好。我尝试更新列表框布局,引发源更新事件,添加/删除项目的其他方法,但没有任何效果。

我尝试调试绑定,但我的绑定太多而无法找到错误。

提前感谢您的任何有用建议。

列表框:

<ListBox x:Name="ListboxUsers" ItemsSource="{Binding Path=AllUsers, Mode=OneWay}" Grid.Column="1" Margin="0" Grid.Row="5" Background="DimGray" BorderThickness="0" Visibility="Hidden" SelectionChanged="ListboxUsers_SelectionChanged"/>

代码隐藏:

CatalogueGrid.DataContext = DataViewModel.Instance;    //whole view model added as datacontext

数据视图模型类:

public class DataViewModel : INotifyPropertyChanged
{
    private static DataViewModel _dataViewModel;
    private Collection<UserModel> allUsers;
    public Collection<UserModel> AllUsers
    {
        get
        {
            return allUsers;
        }
        set
        {
            allUsers = value;
            NotifyPropertyChanged("AllUsers");
        }
    }

    private DataViewModel()
    {
        AllUsers = new Collection<UserModel>();
    }    
    public event PropertyChangedEventHandler PropertyChanged;
    private void NotifyPropertyChanged(string info)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(info));
        }
    }
    .
    .
    .
}

项源绑定不更新值

如果

Collection实现了INotifyCollectionChanged接口,则改用ObservableColLection

private ObservableCollection<UserModel> allUsers;
public ObservableCollection<UserModel> AllUsers
{
    get
    {
        return allUsers;
    }
    set
    {
        allUsers = value;
        NotifyPropertyChanged("AllUsers");
    }
}
要使

对集合的更改传播到 UI,集合类需要实现INotifyCollectionChanged

已经实现此功能的一个非常有用的类是ObservableCollection<T>(MSDN)。使用它而不是Collection<T>.

您已将列表框绑定到一个Collection<T> - 这只是一个列表,它不会向绑定属性发出任何通知,说明其内容已更改。因此,您的列表框不可能知道集合何时更改。

相反,您可以使用 ObservableCollection<T> 类(或者更准确地说,任何也实现 INotifyCollectionChanged 的集合),更改将自动传播到列表框。

注意你的属性不必类型化ObservableCollection<T>,你也可以只声明你的公共属性为IEnumerable<T>IList<T>;绑定会自行找出返回的类是否也实现INotifyCollectionChanged。像这样,您可以稍后自由地替换实际的基础集合类,例如用 ReadOnlyObservableCollection<T> 替换,以防您想要禁止来自外部的更改。

说到这里,关于您的代码的注释:您已经为您的AllUsers属性提供了一个二传手。这可能会导致意外后果,因为您为其他一些代码打开了将属性设置为 null 的可能性,这(取决于代码的其余部分)可能会导致异常。除非您确实希望允许分配新值,否则对于 ItemsSource 属性绑定,只要返回的集合对象实现 INotifyCollectionChanged ,只读属性就完全足够了。