收集更改时,不会通知Datagrid

时间:2022-07-05 09:06:13

I have a datagrid in my window. Above that I have two datepickers StartingDate and EndingDate.

我的窗口中有一个数据网格。在上面我有两个datepickers StartingDate和EndingDate。

When starting date or ending date changes I want to filter datagrid.

当开始日期或结束日期更改时,我想过滤datagrid。

I have my logic of filtering in viewmodel but datagrid is not notified when the Source changes.

我在viewmodel中有过滤的逻辑,但在Source更改时不会通知datagrid。

Here is my code:

这是我的代码:

<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>

Here is viewmodel:

这是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 个解决方案

#1


1  

The source collection must implement INotifyCollectionChanged Interface so the UI knows when it get updated. The easiest way to do this is change IEnumerable<Patient> to ObservableCollection<Patient>

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

You can implement AddRange using extension method like below:

您可以使用扩展方法实现AddRange,如下所示:

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

#2


0  

You're not calling OnPropertyChanged("FilteredPatients") after you finish adding/removing items. That should be all you need to do.

完成添加/删除项目后,您不会调用OnPropertyChanged(“FilteredPatients”)。这应该就是你需要做的。

I know they don't have the AddRange you want, but ObservableCollection<T> and BindingList<T> will automatically do what you want in terms of WPF and notifying.

我知道他们没有你想要的AddRange,但ObservableCollection 和BindingList 将自动按照WPF和通知的方式做你想做的事。

#3


0  

You can implement AddRange() in Observable collection as below (Link) or call OnPropertyChanged("FilteredPatients"); end of PatientsAfterFilter()

您可以在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);
        }

#4


0  

ObservableCollection<T> implements INotifyCollectionChanged implicitly. To get UI refresh your underlying itemsSource list should implement that interface so that UI gets notified on any addition/deletion in this list.

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

So, you should change FilteredPatients to ObservableCollection<Patient> from List<Patient>.

因此,您应该从List 将FilteredPatients更改为ObservableCollection

#1


1  

The source collection must implement INotifyCollectionChanged Interface so the UI knows when it get updated. The easiest way to do this is change IEnumerable<Patient> to ObservableCollection<Patient>

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

You can implement AddRange using extension method like below:

您可以使用扩展方法实现AddRange,如下所示:

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

#2


0  

You're not calling OnPropertyChanged("FilteredPatients") after you finish adding/removing items. That should be all you need to do.

完成添加/删除项目后,您不会调用OnPropertyChanged(“FilteredPatients”)。这应该就是你需要做的。

I know they don't have the AddRange you want, but ObservableCollection<T> and BindingList<T> will automatically do what you want in terms of WPF and notifying.

我知道他们没有你想要的AddRange,但ObservableCollection 和BindingList 将自动按照WPF和通知的方式做你想做的事。

#3


0  

You can implement AddRange() in Observable collection as below (Link) or call OnPropertyChanged("FilteredPatients"); end of PatientsAfterFilter()

您可以在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);
        }

#4


0  

ObservableCollection<T> implements INotifyCollectionChanged implicitly. To get UI refresh your underlying itemsSource list should implement that interface so that UI gets notified on any addition/deletion in this list.

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

So, you should change FilteredPatients to ObservableCollection<Patient> from List<Patient>.

因此,您应该从List 将FilteredPatients更改为ObservableCollection