CollectionViewSource的数据绑定未更新,该源已被分组或排序

时间:2014-12-30 09:02:38

标签: c# listview windows-runtime windows-store-apps grouping

我有一个Windows应用商店应用(或Metro风格/ WinRT / Windows运行时),它有一个CollectionViewSource,它绑定到代码隐藏文件中的ListView。没有排序和/或分组所有工作正常,UI得到更新。但是只要我对CollectionViewSource的Source进行排序或分组,UI就会停止更新。在MainPage中设置绑定:

public MainPage()
{
    InitializeComponent();

    ViewModel = new MainPageVm();
    DataContext = ViewModel;

    Binding myBinding = new Binding();
    myBinding.Mode = BindingMode.TwoWay;
    myBinding.Source = ViewModel.UpcomingAppointments;
    UpcomingListView.SetBinding(ListView.ItemsSourceProperty, myBinding);
    //Timer to update the UI periodically
    var Timer = new DispatcherTimer {Interval = TimeSpan.FromSeconds(60)};
    Timer.Tick += (o, e) => ViewModel.LoadData();
    Timer.Start();
}

viewmodel的相关部分:

public class MainPageVm : INotifyPropertyChanged
{
    public MainPageVm()
    {
        Appointments = new ObservableCollection<Appointment>();
        Appointments.CollectionChanged += delegate { NotifyPropertyChanged("UpcomingAppointments"); };
    }


    public ObservableCollection<Appointment> Appointments
    {
        get { return appointments; }
        set
        {
            if (appointments != value)
            {
                appointments = value;
                NotifyPropertyChanged();
                NotifyPropertyChanged("UpcomingAppointments");
            }
        }
    }


    public CollectionViewSource UpcomingAppointments
    {
        get
        {
            return new CollectionViewSource
            {
               //removing Where an Groupby and set IsSourceGrouped = false get the UI updated again
                Source = Appointments
                    .Where(a => a.Start > DateTime.UtcNow) 
                    .GroupBy(x => x.Day),
                IsSourceGrouped = true
            }; 
        }
    }


    public async Task LoadData()
    {
        var Repo = new WebserviceRepository();
        await Repo.GetAppointments();

        Appointments.Clear;
        foreach (Appointment Appointment in Repo.Appointments)
        {
            Appointments.Add(Appointment);
        }
        NotifyPropertyChanged("UpcomingAppointments");
        NotifyPropertyChanged("Appointments");
    }


    public event PropertyChangedEventHandler PropertyChanged;
    public void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }       

相关的XAML部分:

<ListView Name="UpcomingListView" ItemTemplate="{StaticResource AppointmentListTemplate}">              

<ListView.GroupStyle>
    <GroupStyle HidesIfEmpty="False">
        <GroupStyle.HeaderTemplate>
            <DataTemplate>
                <Grid>
                    <TextBlock Text="{Binding Key}" />
                </Grid>
            </DataTemplate>
        </GroupStyle.HeaderTemplate>
    </GroupStyle>
</ListView.GroupStyle>

最后是约会课:

public class Appointment
{
    public Guid AppointmentId { get; set; }
    public string Description { get; set; }
    public DateTime Start { get; set; }
    public DateTime End { get; set; }
    public string Day
    {
        get
        { 
           if (this.Start.Date == DateTime.Now.Date){return "Today";}
           if (this.Start.Date == (DateTime.Now.AddDays(1).Date)) { return "Tomorrow";}
           If (this.Start.Date == (DateTime.Now.AddDays(2).Date)){ return "Day After Tomorrow";}
           return string.Empty;         
        }
    }
}

因此,删除.Where和.Sort并将IsSourceGrouped设置为false会再次更新UI,但当然是未排序的,而不是所需的分组。

当我在ViewModel的构造函数中设置数据时,该数据会显示(分组与否)但不会更新

正如您所看到的,每当运行LoadData时我都会调用NotifyPropertyChanged,以确保它被调用。在Appointments OberservableCollection-s Collection更改后,我也运行NotifyPropertyChanged。

显然,Where过滤和GroupBy分组需要一些我不知道的其他调整。我在SO上看到很多关于分组的问题,但似乎它们是关于WPF(并且这是不同的)或者在XAML中设置所有绑定和静态资源(我不想这样做)。

所以我的基本问题是:如何使用C#代码隐藏文件对ListView中的UpcomingAppointments进行分组和排序?

0 个答案:

没有答案