ItemsSource绑定不更新值

时间:2015-01-02 19:16:30

标签: c# wpf xaml

我需要制作物品清单。我将用户集合绑定到列表框。一切都很好,但列表框中的项目不会实时更新。它们根本没有更新。因此,当我从列表中删除任何用户时,即使其源已正确更改,列表框也不会更新。

Source位于路径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

DataViewModel类:

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));
        }
    }
    .
    .
    .

}

3 个答案:

答案 0 :(得分:6)

如果ObservableColLection实现了Collection接口,则使用INotifyCollectionChanged

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

答案 1 :(得分:5)

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

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

答案 2 :(得分:3)

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

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

请注意,您的媒体资源 无法输入ObservableCollection<T>,您也可以将公共媒体资源声明为IEnumerable<T>IList<T>;绑定将自行查明返回的类是否也实现了INotifyCollectionChanged。像这样,您可以稍后替换您的实际底层集合类,例如使用ReadOnlyObservableCollection<T>,以防您想要禁止来自外部的更改。

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