收集更改时,不会通知Datagrid

时间:2013-12-27 02:57:30

标签: c# wpf xaml mvvm datagrid

我的datagrid中有一个window。在此之上,我有两个日期选择器StartingDateEndingDate

starting dateending date更改时,我想过滤数据网格。

我在viewmodel中有过滤的逻辑,但是当Source发生变化时,不会通知datagrid。

这是我的代码:

<TextBlock Grid.Column="3" Text="Starting Date :" FontSize="18" Margin="5" />
<DatePicker Grid.Column="4"  FontSize="18" SelectedDate="{Binding StartingDate}"/>
<TextBlock Grid.Column="6" Text="Ending Date :" FontSize="18" Margin="5" />
<DatePicker Grid.Column="7"  FontSize="18" SelectedDate="{Binding EndingDate}"/>

<DataGrid Grid.Row="1" AutoGenerateColumns="False" FontSize="18" RowDetailsVisibilityMode="VisibleWhenSelected"
          IsReadOnly="True" SelectionMode="Single" SelectionUnit="FullRow" Margin="0,10"
          ItemsSource="{Binding DataContext.FilteredPatients, 
                                RelativeSource={RelativeSource AncestorType={x:Type Window}},
                                TargetNullValue=''}">

    <DataGrid.Resources>
        <Style x:Key="VerticalCenter" TargetType="TextBlock">
            <Setter Property="VerticalAlignment" Value="Center"></Setter>
        </Style>
        <Style x:Key="VerticalAndHorizontalCenter" TargetType="FrameworkElement" >
            <Setter Property="VerticalAlignment" Value="Center"></Setter>
            <Setter Property="HorizontalAlignment" Value="Center"></Setter>
        </Style>
        <Style x:Key="VerticalAndHorizontalCenterTextBlock" TargetType="TextBlock"
           BasedOn="{StaticResource VerticalAndHorizontalCenter}"/>
        <Style x:Key="VerticalAndHorizontalCenterHeader" TargetType="{x:Type DataGridColumnHeader}" 
           BasedOn="{StaticResource VerticalAndHorizontalCenter}"/>
    </DataGrid.Resources>

    <DataGrid.Columns>
        <DataGridTextColumn Header="Name" Binding="{Binding Name}" Width="25*" 
                            ElementStyle="{StaticResource VerticalCenter}"/>
        <DataGridTextColumn Header="City" Binding="{Binding City}" Width="15*" 
                            ElementStyle="{StaticResource VerticalAndHorizontalCenterTextBlock}" 
                            HeaderStyle="{StaticResource VerticalAndHorizontalCenterHeader}"/>
        <DataGridTextColumn Header="Sex" Binding="{Binding Name}" Width="10*" 
                        ElementStyle="{StaticResource VerticalAndHorizontalCenterTextBlock}" 
                        HeaderStyle="{StaticResource VerticalAndHorizontalCenterHeader}"/>
        <DataGridTextColumn Header="Age" Binding="{Binding Age}" Width="5*" 
                        ElementStyle="{StaticResource VerticalAndHorizontalCenterTextBlock}" 
                        HeaderStyle="{StaticResource VerticalAndHorizontalCenterHeader}"/>
        <DataGridTemplateColumn Header="Delete">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <Button Focusable="False" Command="{Binding DataContext.DeletePatientCommand, RelativeSource={RelativeSource AncestorType={x:Type Window}}}" Height="Auto" Width="Auto">
                        <Image Source="Images/DeletePatient.png" Height="32" Width="32"/>
                    </Button>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
    </DataGrid.Columns>
</DataGrid>

这是viewmodel:

public class MainWindowViewModel : INotifyPropertyChanged
{

    public MainWindowViewModel()
    {
        using (Lab_Lite_Entities db = new Lab_Lite_Entities())
        {
            Patients = db.Patients.ToList();
            FilteredPatients = db.Patients.ToList();
        }
    }

    private IEnumerable<Patient> patients;
    public IEnumerable<Patient> Patients
    {
        get
        {
            return patients;
        }
        set
        {
            patients = value;
            OnPropertyChanged("Patients");
        }
    }

    private DateTime? startingDate;
    public DateTime? StartingDate
    {
        get
        {
            return startingDate;
        }
        set
        {
            startingDate = value;
            OnPropertyChanged("StartingDate");
            PatientsAfterFilter();
        }
    }

    private DateTime? endingDate;
    public DateTime? EndingDate
    {
        get
        {
            return endingDate;
        }
        set
        {
            endingDate = value;
            OnPropertyChanged("EndingDate");
            PatientsAfterFilter();
        }
    }

    private void PatientsAfterFilter()
    {

        if (PatientNameToFilter == null && (StartingDate != null && EndingDate == null))
        {
            using (Lab_Lite_Entities db = new Lab_Lite_Entities())
            {

                FilteredPatients.Clear();

                if (db.Patients.Where(p => p.HaemogramReports.Any(h => h.ReportDate >= StartingDate)).Select(p => p).ToList().Count() > 0)
                {
                    FilteredPatients.AddRange(db.Patients.Where(p => p.HaemogramReports.Any(h => h.ReportDate >= StartingDate)).Select(p => p).ToList());
                }
                if (db.Patients.Where(p => p.UrineAnalysises.Any(u => u.ReportDate >= StartingDate)).Select(p => p).ToList().Count() > 0)
                {
                    {
                        FilteredPatients.AddRange(db.Patients.Where(p => p.UrineAnalysises.Any(u => u.ReportDate >= StartingDate)).Select(p => p).ToList());
                    }
                }
                if (db.Patients.Where(p => p.BloodChemistries.Any(b => b.ReportDate >= StartingDate)).Select(p => p).ToList().Count() > 0)
                {
                    FilteredPatients.AddRange(db.Patients.Where(p => p.BloodChemistries.Any(b => b.ReportDate >= StartingDate)).Select(p => p).ToList());
                }
                if (db.Patients.Where(p => p.WidalTests.Any(w => w.ReportDate >= StartingDate)).Select(p => p).ToList().Count() > 0)
                {
                    FilteredPatients.AddRange(db.Patients.Where(p => p.WidalTests.Any(w => w.ReportDate >= StartingDate)).Select(p => p).ToList());
                }
                if (db.Patients.Where(p => p.SerologicalTests.Any(s => s.ReportDate >= StartingDate)).Select(p => p).ToList().Count() > 0)
                {
                    FilteredPatients.AddRange(db.Patients.Where(p => p.SerologicalTests.Any(s => s.ReportDate >= StartingDate)).Select(p => p).ToList());
                }
                if (db.Patients.Where(p => p.DengueTests.Any(d => d.ReportDate >= StartingDate)).Select(p => p).ToList().Count() > 0)
                {
                    FilteredPatients.AddRange(db.Patients.Where(p => p.DengueTests.Any(d => d.ReportDate >= StartingDate)).Select(p => p).ToList());
                }
                if (db.Patients.Where(p => p.HIVTests.Any(h => h.ReportDate >= StartingDate)).Select(p => p).ToList().Count() > 0)
                {
                    FilteredPatients.AddRange(db.Patients.Where(p => p.HIVTests.Any(h => h.ReportDate >= StartingDate)).Select(p => p).ToList());
                }
                if (db.Patients.Where(p => p.Troponin1Tests.Any(t => t.ReportDate >= StartingDate)).Select(p => p).ToList().Count() > 0)
                {
                    FilteredPatients.AddRange(db.Patients.Where(p => p.Troponin1Tests.Any(t => t.ReportDate >= StartingDate)).Select(p => p).ToList());
                }
                if (db.Patients.Where(p => p.UrinaryPregnancyCardTests.Any(u => u.ReportDate >= StartingDate)).Select(p => p).ToList().Count() > 0)
                {
                    FilteredPatients.AddRange(db.Patients.Where(p => p.UrinaryPregnancyCardTests.Any(u => u.ReportDate >= StartingDate)).Select(p => p).ToList());
                }
                if (db.Patients.Where(p => p.LiverFunctionTests.Any(l => l.ReportDate >= StartingDate)).Select(p => p).ToList().Count() > 0)
                {
                    FilteredPatients.AddRange(db.Patients.Where(p => p.LiverFunctionTests.Any(l => l.ReportDate >= StartingDate)).Select(p => p).ToList());
                }
            }
        }
        else if (PatientNameToFilter == null && (StartingDate == null && EndingDate != null))
        {

            FilteredPatients.Clear();

            using (Lab_Lite_Entities db = new Lab_Lite_Entities())
            {
                if (db.Patients.Where(p => p.HaemogramReports.Any(h => h.ReportDate <= EndingDate)).Select(p => p).ToList().Count() > 0)
                {
                    FilteredPatients.AddRange(db.Patients.Where(p => p.HaemogramReports.Any(h => h.ReportDate <= EndingDate)).Select(p => p).ToList());
                }
                if (db.Patients.Where(p => p.UrineAnalysises.Any(u => u.ReportDate <= EndingDate)).Select(p => p).ToList().Count() > 0)
                {
                    FilteredPatients.AddRange(db.Patients.Where(p => p.UrineAnalysises.Any(u => u.ReportDate <= EndingDate)).Select(p => p).ToList());
                }
                if (db.Patients.Where(p => p.BloodChemistries.Any(b => b.ReportDate <= EndingDate)).Select(p => p).ToList().Count() > 0)
                {
                    FilteredPatients.AddRange(db.Patients.Where(p => p.BloodChemistries.Any(b => b.ReportDate <= EndingDate)).Select(p => p).ToList());
                }
                if (db.Patients.Where(p => p.WidalTests.Any(w => w.ReportDate <= EndingDate)).Select(p => p).ToList().Count() > 0)
                {
                    FilteredPatients.AddRange(db.Patients.Where(p => p.WidalTests.Any(w => w.ReportDate <= EndingDate)).Select(p => p).ToList());
                }
                if (db.Patients.Where(p => p.SerologicalTests.Any(s => s.ReportDate <= EndingDate)).Select(p => p).ToList().Count() > 0)
                {
                    FilteredPatients.AddRange(db.Patients.Where(p => p.SerologicalTests.Any(s => s.ReportDate <= EndingDate)).Select(p => p).ToList());
                }
                if (db.Patients.Where(p => p.DengueTests.Any(d => d.ReportDate <= EndingDate)).Select(p => p).ToList().Count() > 0)
                {
                    FilteredPatients.AddRange(db.Patients.Where(p => p.DengueTests.Any(d => d.ReportDate <= EndingDate)).Select(p => p).ToList());
                }
                if (db.Patients.Where(p => p.HIVTests.Any(h => h.ReportDate <= EndingDate)).Select(p => p).ToList().Count() > 0)
                {
                    FilteredPatients.AddRange(db.Patients.Where(p => p.HIVTests.Any(h => h.ReportDate <= EndingDate)).Select(p => p).ToList());
                }
                if (db.Patients.Where(p => p.Troponin1Tests.Any(t => t.ReportDate <= EndingDate)).Select(p => p).ToList().Count() > 0)
                {
                    FilteredPatients.AddRange(db.Patients.Where(p => p.Troponin1Tests.Any(t => t.ReportDate <= EndingDate)).Select(p => p).ToList());
                }
                if (db.Patients.Where(p => p.UrinaryPregnancyCardTests.Any(u => u.ReportDate <= EndingDate)).Select(p => p).ToList().Count() > 0)
                {
                    FilteredPatients.AddRange(db.Patients.Where(p => p.UrinaryPregnancyCardTests.Any(u => u.ReportDate <= EndingDate)).Select(p => p).ToList());
                }
                if (db.Patients.Where(p => p.LiverFunctionTests.Any(l => l.ReportDate <= EndingDate)).Select(p => p).ToList().Count() > 0)
                {
                    FilteredPatients.AddRange(db.Patients.Where(p => p.LiverFunctionTests.Any(l => l.ReportDate <= EndingDate)).Select(p => p).ToList());
                }
            }
        }
        else if (PatientNameToFilter == null && (StartingDate != null && EndingDate != null))
        {

            FilteredPatients.Clear();

            using (Lab_Lite_Entities db = new Lab_Lite_Entities())
            {
                if (db.Patients.Where(p => p.HaemogramReports.Any(h => h.ReportDate >= StartingDate && h.ReportDate <= EndingDate)).Select(p => p).ToList().Count() > 0)
                {
                    FilteredPatients.AddRange(db.Patients.Where(p => p.HaemogramReports.Any(h => h.ReportDate >= StartingDate && h.ReportDate <= EndingDate)).Select(p => p).ToList());
                }
                if (db.Patients.Where(p => p.UrineAnalysises.Any(u => u.ReportDate >= StartingDate && u.ReportDate <= EndingDate)).Select(p => p).ToList().Count() > 0)
                {
                    FilteredPatients.AddRange(db.Patients.Where(p => p.UrineAnalysises.Any(u => u.ReportDate >= StartingDate && u.ReportDate <= EndingDate)).Select(p => p).ToList());
                }
                if (db.Patients.Where(p => p.BloodChemistries.Any(b => b.ReportDate >= StartingDate && b.ReportDate <= EndingDate)).Select(p => p).ToList().Count() > 0)
                {
                    FilteredPatients.AddRange(db.Patients.Where(p => p.BloodChemistries.Any(b => b.ReportDate >= StartingDate && b.ReportDate <= EndingDate)).Select(p => p).ToList());
                }
                if (db.Patients.Where(p => p.WidalTests.Any(w => w.ReportDate >= StartingDate && w.ReportDate <= EndingDate)).Select(p => p).ToList().Count() > 0)
                {
                    FilteredPatients.AddRange(db.Patients.Where(p => p.WidalTests.Any(w => w.ReportDate >= StartingDate && w.ReportDate <= EndingDate)).Select(p => p).ToList());
                }
                if (db.Patients.Where(p => p.SerologicalTests.Any(s => s.ReportDate >= StartingDate && s.ReportDate <= EndingDate)).Select(p => p).ToList().Count() > 0)
                {
                    FilteredPatients.AddRange(db.Patients.Where(p => p.SerologicalTests.Any(s => s.ReportDate >= StartingDate && s.ReportDate <= EndingDate)).Select(p => p).ToList());
                }
                if (db.Patients.Where(p => p.DengueTests.Any(d => d.ReportDate >= StartingDate && d.ReportDate <= EndingDate)).Select(p => p).ToList().Count() > 0)
                {
                    FilteredPatients.AddRange(db.Patients.Where(p => p.DengueTests.Any(d => d.ReportDate >= StartingDate && d.ReportDate <= EndingDate)).Select(p => p).ToList());
                }
                if (db.Patients.Where(p => p.HIVTests.Any(h => h.ReportDate >= StartingDate && h.ReportDate <= EndingDate)).Select(p => p).ToList().Count() > 0)
                {
                    FilteredPatients.AddRange(db.Patients.Where(p => p.HIVTests.Any(h => h.ReportDate >= StartingDate && h.ReportDate <= EndingDate)).Select(p => p).ToList());
                }
                if (db.Patients.Where(p => p.Troponin1Tests.Any(t => t.ReportDate >= StartingDate && t.ReportDate <= EndingDate)).Select(p => p).ToList().Count() > 0)
                {
                    FilteredPatients.AddRange(db.Patients.Where(p => p.Troponin1Tests.Any(t => t.ReportDate >= StartingDate && t.ReportDate <= EndingDate)).Select(p => p).ToList());
                }
                if (db.Patients.Where(p => p.UrinaryPregnancyCardTests.Any(u => u.ReportDate >= StartingDate && u.ReportDate <= EndingDate)).Select(p => p).ToList().Count() > 0)
                {
                    FilteredPatients.AddRange(db.Patients.Where(p => p.UrinaryPregnancyCardTests.Any(u => u.ReportDate >= StartingDate && u.ReportDate <= EndingDate)).Select(p => p).ToList());
                }
                if (db.Patients.Where(p => p.LiverFunctionTests.Any(l => l.ReportDate >= StartingDate && l.ReportDate <= EndingDate)).Select(p => p).ToList().Count() > 0)
                {
                    FilteredPatients.AddRange(db.Patients.Where(p => p.LiverFunctionTests.Any(l => l.ReportDate >= StartingDate && l.ReportDate <= EndingDate)).Select(p => p).ToList());
                }
            }
        }
        else
        {
            if (Patients != null)
            {
                FilteredPatients = Patients.ToList();
            }
        }

    }

    private List<Patient> filteredPatients;
    public List<Patient> FilteredPatients
    {
        get
        {
            return filteredPatients;
        }
        set
        {
            filteredPatients = value;
            OnPropertyChanged("FilteredPatients");
        }
    }

    private void OnPropertyChanged(string PropertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(PropertyName));
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
}

4 个答案:

答案 0 :(得分:1)

源集合必须实现INotifyCollectionChanged Interface,以便UI知道何时更新。最简单的方法是将IEnumerable<Patient>更改为ObservableCollection<Patient>

您可以使用以下扩展方法实现AddRange:

public static void AddRange<T>(this ObservableCollection<T> source, IEnumerable<T> list)
{
    foreach (var item in list)
    {
        source.Add(item);
    }
}

答案 1 :(得分:0)

完成添加/删除项目后,您没有致电OnPropertyChanged("FilteredPatients")。这应该就是你需要做的一切。

我知道他们没有您想要的AddRange,但是ObservableCollection<T>BindingList<T>会根据WPF自动执行您想要的操作并通知。

答案 2 :(得分:0)

您可以在Observable集合中实现AddRange(),如下所示(Link)或致电OnPropertyChanged("FilteredPatients"); PatientsAfterFilter()

结尾
public void AddRange(IEnumerable<T> dataToAdd)
        {
            this.CheckReentrancy();

            //
            // We need the starting index later
            //
            int startingIndex = this.Count;

            //
            // Add the items directly to the inner collection

            //
            foreach (var data in dataToAdd)
            {
                this.Items.Add(data);
            }

            //
            // Now raise the changed events
            //
            this.OnPropertyChanged("Count");
            this.OnPropertyChanged("Item[]");

            //
            // We have to change our input of new items into an IList since that is what the
            // event args require.
            //
            var changedItems = new List<T>(dataToAdd);
            this.OnCollectionChanged(changedItems, startingIndex);
        }

答案 3 :(得分:0)

ObservableCollection<T>隐式实现INotifyCollectionChanged。要获取UI刷新您的基础itemsSource列表应该实现该接口,以便UI在此列表中的任何添加/删除时得到通知。

因此,您应该从FilteredPatientsObservableCollection<Patient>更改为List<Patient>