【问题标题】:ListView bound to a derived collection not updating (XAML / Windows 8)ListView 绑定到未更新的派生集合(XAML / Windows 8)
【发布时间】:2012-11-19 13:04:04
【问题描述】:

我正在尝试通过基于特定标准创建 Observable Collection 的“视图”来转换我的数据。这是一个简单的例子。

我有两个 ListView。一个直接绑定到Dates 的集合,另一个绑定到使用Where(x => x.Date > DateTime.Today) 从第一个集合派生的DatesAfterToday 集合

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

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

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

【问题讨论】:

    标签: c# xaml listview windows-8 observablecollection


    【解决方案1】:

    修改你的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 接口公开。因此,您可以做的就是在 _Dates 集合被修改时向 DatesAfterToday 发出通知。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-10-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多