A question we've had quite a few times is how to add a “select-all” button to the AutoFilterControl along with the "Clear All" button to have something that mimics Excel's filtering.
The steps to do this are:
- Create an explicit style that targets AutoFilterControl and sets the Template property.
- Change the template basing it on our default AutoFilterControl template found in the themes folder of the DataGridControl's installation folder.
- Add the “select-all” button and handle its Click event in order to add the custom logic that selects all the AutoFilterValues of that column by adding all the distinct values to the AutoFilterValues.
- Apply this style to all the columns by setting it to the AutoFilterControlStyle that property of the columns that you want to have the "select-all" button. Note that if your collection has a larger number of distinct items, the “select-all” procedure might freeze the UI for a while until the AutoFilterValues are all populated. We can however increase the performance by using DeferINotifyCollectionChanged on the AutoFilterValues.
This is the style:
<Style x:Key="PART_AutoFilterControlStyle" TargetType="{x:Type xcdg:AutoFilterControl}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type xcdg:AutoFilterControl}">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Button Content=“select-all”
Click="OnAutoFilterSelectClearAllClick"
Grid.Row="0"
MinHeight="24"
Tag="1"/>
<Button Content="Clear All"
Click="OnAutoFilterSelectClearAllClick"
Grid.Row="1"
MinHeight="24"
Tag="0"/>
<ListBox Name="PART_DistinctValuesHost"
Background="{TemplateBinding Background}"
BorderThickness="0"
Foreground="{TemplateBinding Foreground}"
Grid.Row="2"
ItemTemplate="{TemplateBinding DistinctValueItemTemplate}"
ItemTemplateSelector="{TemplateBinding DistinctValueItemTemplateSelector}"
ItemContainerStyle="{TemplateBinding DistinctValueItemContainerStyle}"
ItemContainerStyleSelector="{TemplateBinding DistinctValueItemContainerStyleSelector}"
MaxHeight="350"
SelectionMode="Multiple"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"/>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Applying the style to all the columns:
myGrid.ItemsSourceChangeCompleted += new EventHandler( myGrid_ItemsSourceChangeCompleted );
void myGrid_ItemsSourceChangeCompleted( object sender, EventArgs e )
{
foreach( var col in myGrid.Columns )
col.AutoFilterControlStyle = ( Style )FindResource( "PART_AutoFilterControlStyle" );
}
Handling the click event of the “select-all” button:
private void OnAutoFilterSelectClearAllClick( object sender, RoutedEventArgs e )
{
DataGridCollectionView dataGridCollectionView = ( DataGridCollectionView )myGrid.ItemsSource;
if( dataGridCollectionView != null )
{
int filters = 0;
System.Windows.Controls.Button button = ( System.Windows.Controls.Button )sender;
AutoFilterControl autoFilterControl = button.TemplatedParent as AutoFilterControl;
string columnFieldName = autoFilterControl.AutoFilterColumn.FieldName;
bool selectAll = ( ( string )button.Tag ) == "1";
using( dataGridCollectionView.DeferRefresh() )
{
ObservableHashList autoFilterValues = dataGridCollectionView.AutoFilterValues[ columnFieldName ] as ObservableHashList;
using( autoFilterValues.DeferINotifyCollectionChanged() )
{
autoFilterValues.Clear();
if( selectAll )
{
IList distinctValues = dataGridCollectionView.DistinctValues[ columnFieldName ];
foreach( object value in distinctValues )
autoFilterValues.Add( value );
filters += distinctValues.Count;
}
}
if( selectAll )
{
ListBox listBox = autoFilterControl.DistinctValuesHost as ListBox;
listBox.SelectAll();
}
}
}
}
And that’s about it! You can download a sample application HERE ! 