I have some markup:
<Window.Resources>
<CollectionViewSource x:Key="cvsStudentList" Source="{StaticResource StudentList}" Filter="CollectionViewSource_Filter">
</CollectionViewSource>
</Window.Resources>
It sets up a CollectionViewSource
and implements a Filter
handler:
private void CollectionViewSource_Filter(object sender, FilterEventArgs e)
{
Student oStudent = e.Item as Student;
if (oStudent != null &&
textStudentFilter != null &&
checkGenderMale != null &&
checkGenderFemale != null &&
checkNeverAssigned != null &&
checkElder != null &&
checkMinisterialServant != null &&
checkNotAppointed != null &&
checkRegularPioneer != null &&
checkPublisher != null &&
checkUnbaptisedOrStudying != null)
{
bool bFilterGenderOK = false;
bool bFilterNameOK = false;
bool bFilterNeverAssignedOK = false;
bool bFilterAppointedOK = false;
bool bFilterServingOK = false;
// Gender
if (!checkGenderMale.IsChecked.GetValueOrDefault() && !checkGenderFemale.IsChecked.GetValueOrDefault())
bFilterGenderOK = true; // We are not filtering gender
else
{
if (checkGenderMale.IsChecked.GetValueOrDefault() && oStudent.Gender == StudentGender.Male)
bFilterGenderOK = true;
else if (checkGenderFemale.IsChecked.GetValueOrDefault() && oStudent.Gender == StudentGender.Female)
bFilterGenderOK = true;
}
// Name
if (textStudentFilter.Text == "")
bFilterNameOK = true; // We are not filtering the name
else
{
if (oStudent.Name.IndexOf(textStudentFilter.Text, StringComparison.OrdinalIgnoreCase) >= 0)
bFilterNameOK = true;
}
// Never Assigned
if (!checkNeverAssigned.IsChecked.GetValueOrDefault())
bFilterNeverAssignedOK = true; // We are not filtering never assigned
else
bFilterNeverAssignedOK = oStudent.NeverAssigned;
// Appointed
if((checkElder.IsChecked.Value && oStudent.Appointed == StudentAppointed.Elder) ||
(checkMinisterialServant.IsChecked.Value && oStudent.Appointed == StudentAppointed.MinisterialServant) ||
(checkNotAppointed.IsChecked.Value && oStudent.Appointed == StudentAppointed.NotAppointed))
{
bFilterAppointedOK = true;
}
// Serving
if ((checkRegularPioneer.IsChecked.Value && oStudent.Serving == StudentServing.RegularPioneer) ||
(checkPublisher.IsChecked.Value && oStudent.Serving == StudentServing.Publisher) ||
(checkUnbaptisedOrStudying.IsChecked == null && oStudent.Serving == StudentServing.Studying) ||
(checkUnbaptisedOrStudying.IsChecked.HasValue && checkUnbaptisedOrStudying.IsChecked.Value
&& (oStudent.Serving == StudentServing.UnbaptisedPublisher || oStudent.Serving == StudentServing.Studying)))
{
bFilterServingOK = true;
}
if(bFilterGenderOK && bFilterNameOK && bFilterNeverAssignedOK && bFilterAppointedOK && bFilterServingOK)
e.Accepted = true;
else
e.Accepted = false;
}
}
The controls on the panel:
To trigger the view refresh, I have the following handers:
private void textStudentFilter_TextChanged(object sender, TextChangedEventArgs e)
{
// Refresh the view to apply filters.
CollectionViewSource.GetDefaultView(gridStudents.ItemsSource).Refresh();
}
private void checkGenderMale_Click(object sender, RoutedEventArgs e)
{
// Refresh the view to apply filters.
CollectionViewSource.GetDefaultView(gridStudents.ItemsSource).Refresh();
}
private void checkGenderFemale_Click(object sender, RoutedEventArgs e)
{
// Refresh the view to apply filters.
CollectionViewSource.GetDefaultView(gridStudents.ItemsSource).Refresh();
}
private void checkNeverAssigned_Click(object sender, RoutedEventArgs e)
{
// Refresh the view to apply filters.
CollectionViewSource.GetDefaultView(gridStudents.ItemsSource).Refresh();
}
private void checkElder_Click(object sender, RoutedEventArgs e)
{
if (!checkElder.IsChecked.Value && !checkMinisterialServant.IsChecked.Value)
checkNotAppointed.IsChecked = true;
// Refresh the view to apply filters.
CollectionViewSource.GetDefaultView(gridStudents.ItemsSource).Refresh();
}
private void checkMinisterialServant_Click(object sender, RoutedEventArgs e)
{
if (!checkElder.IsChecked.Value && !checkMinisterialServant.IsChecked.Value)
checkNotAppointed.IsChecked = true;
// Refresh the view to apply filters.
CollectionViewSource.GetDefaultView(gridStudents.ItemsSource).Refresh();
}
private void checkNotAppointed_Click(object sender, RoutedEventArgs e)
{
// Refresh the view to apply filters.
CollectionViewSource.GetDefaultView(gridStudents.ItemsSource).Refresh();
}
private void checkRegularPioneer_Click(object sender, RoutedEventArgs e)
{
// Refresh the view to apply filters.
CollectionViewSource.GetDefaultView(gridStudents.ItemsSource).Refresh();
}
private void checkPublisher_Click(object sender, RoutedEventArgs e)
{
// Refresh the view to apply filters.
CollectionViewSource.GetDefaultView(gridStudents.ItemsSource).Refresh();
}
private void checkUnbaptisedPublisher_Click(object sender, RoutedEventArgs e)
{
// Refresh the view to apply filters.
CollectionViewSource.GetDefaultView(gridStudents.ItemsSource).Refresh();
}
private void panelStudentPicker_Loaded(object sender, RoutedEventArgs e)
{
// Refresh the view to apply filters.
CollectionViewSource.GetDefaultView(gridStudents.ItemsSource).Refresh();
}
Can this be done in a better way? As you can see, when the check boxes are toggled, or the text box is changed, I want to refresh the filter. This includes when the form is first loaded.
Thank you for any assistance with this.