c# - 绑定(bind)到派生集合的 ListView 未更新(XAML/Windows 8)

标签 c# xaml listview windows-8 observablecollection

我试图通过基于某些条件创建可观察集合的“ View ”来转换我的数据。这是一个简单的例子。

我有两个 ListView 。一个直接绑定(bind)到 Dates 集合,另一个绑定(bind)到使用 Where(x => x.Date > 派生自第一个集合的 DatesAfterToday 集合日期时间.今天)

当我向 Dates 集合添加新项目时,只有第一个 ListView 发生变化。绑定(bind)到 DatesAfterToday 的 ListView 根本不更新。我尝试将 PropertyChangedEventHandler 添加到 View 模型并在更新日期集合时触发它,但它不起作用。

MainPage.xaml

<StackPanel>
    <ListView x:Name="ListOne" ItemsSource="{Binding Dates}">
        <ListView.ItemTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding Date}"></TextBlock>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
    <ListView x:Name="ListTwo" ItemsSource="{Binding DatesAfterToday}">
        <ListView.ItemTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding Date}"></TextBlock>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
    <Button Click="Button_Click_1">Press Me to Add a Date</Button>
</StackPanel>

查看模型

public class Model : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    public Model()
    {
        _Dates = new ObservableCollection<DateTime>();
    }
    private ObservableCollection<DateTime> _Dates;
    public ObservableCollection<DateTime> Dates
    {
        get
        {
            return _Dates;
        }
        set
        {
            _Dates = value;
            if (PropertyChanged != null){
                PropertyChanged(this, new PropertyChangedEventArgs("_Dates"));
                PropertyChanged(this, new PropertyChangedEventArgs("Dates"));
                PropertyChanged(this, new PropertyChangedEventArgs("DatesAfterToday"));
            }
        }
    }
    public ObservableCollection<DateTime> DatesAfterToday 
    { 
        get {
            return new ObservableCollection<DateTime>(
                _Dates.Where(t => t.Date > DateTime.Today).ToList()
            );
        }
    }
}

MainPage.xaml.cs

public sealed partial class ListTest : Page
{
    public Model model;
    public ListTest()
    {
        this.InitializeComponent();
        model = new Model();
        model.Dates.Add(new DateTime(2012, 11, 12, 0, 0, 0));
        model.Dates.Add(new DateTime(2012, 11, 15, 0, 0, 0));
        model.Dates.Add(new DateTime(2012, 11, 17, 0, 0, 0));
        model.Dates.Add(new DateTime(2012, 11, 20, 0, 0, 0));
        model.Dates.Add(new DateTime(2012, 11, 22, 0, 0, 0));
        this.DataContext = model;
    }

    protected override void OnNavigatedTo(NavigationEventArgs e)
    {
    }

    private void Button_Click_1(object sender, RoutedEventArgs e)
    {
        model.Dates.Add(new DateTime(2012, 11, 24, 0, 0, 0));
    }
}

更新:编辑了问题以使其更易于阅读。

最佳答案

修改您的 Model 构造函数,如下所示:

public Model()
{
    _Dates = new ObservableCollection<DateTime>();

    _Dates.CollectionChanged += (s, e) =>
        {
            var handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs("DatesAfterToday"));
            }
        };
}

问题是,当您从 _Dates 集合中添加/删除项目时,setter 不会被调用,这就是为什么 DatesAfterToday 的属性更改事件是从未提出。

对于集合,WPF 还会注册 CollectionChanged 事件,该事件由 ObservableCollection 实现的 INotifyCollectionChanged 接口(interface)公开。因此,您可以做的是每当修改 _Dates 集合时发出 DatesAfterToday 通知。

关于c# - 绑定(bind)到派生集合的 ListView 未更新(XAML/Windows 8),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13454418/

相关文章:

c# - 以编程方式设置共享点列表项的字段值

c# - 如何以编程方式将 TypedEventHandler 添加到 RoutedEvents?

c# - 通过反射从 C# 访问 C++ 非成员函数

c# - 如何加速 ListBox 渲染和 ListCollectionView 过滤?

.net - 仅在部署的PresentationFramework 中发生XmlParseException

c# - DataBinding 集合和更改集合元素

android - ListView 中膨胀行中某些布局的动画

java - 如何从另一个类更改 imageview 源?

android - 在另一个 Activity 中更新后刷新 ListView

c# - 在 WinForm 应用程序中将入口点移动到 DLL