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
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
#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
So, you should change FilteredPatients
to ObservableCollection<Patient>
from List<Patient>
.
因此,您应该从List
#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
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
#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
So, you should change FilteredPatients
to ObservableCollection<Patient>
from List<Patient>
.
因此,您应该从List