i have zipped up the project file for viewing only thing i cant include is the database itself as its real data but project code is here,
https://www.mediafire.com/file/fmx84oixiqlx7iw/DatabaseFiltering.zip/file
this is the full project.
This browser is no longer supported.
Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.
Good Evening all,
i have been trying for nearly a week now to get this to work but for the life of me cant get this to work the way i want
what i want to do is when the filter is applied it will apply orange on the button of the column its applied too.
as you can see from the image here i have it working in some way,
so got the color to show on colum and button only want it on the button
this filter was attached to sitename so i only want the button colur to show orange for that button and if filter is removed i want it to go back to transapant ,
below is my
MainViewModel
public MainViewModel()
{
ColumnFilters = new Dictionary<string, bool>();
elfenload = new LoadDatabases();
FilterCommand = new RelayCommand(Filter);
ApplyFilterCommand = new RelayCommand(ApplyFilter);
CurrentFilters = new ObservableCollection<Filter>();
elfentable = new Dictionary<string, ObservableCollection<Filter>>();
_databases = new ObservableCollection<LoadDatabases>();
FilteredDatabases = new ObservableCollection<LoadDatabases>();
//Pumps = new ObservableCollection<LoadDatabases>();
FilterTextChangedCommand = new RelayCommand(obj => FilterTextChanged(obj as string));
elfenload.InitialzePumps();
foreach (var item in elfenload.Pumps)
{
FilteredDatabases.Add(item);
_databases.Add(item);
}
foreach (var item in elfenload.Pumps)
{
foreach (var prop in typeof(LoadDatabases).GetProperties())
{
var columnName = prop.Name;
var columnValue = prop.GetValue(item)?.ToString();
if (!string.IsNullOrEmpty(columnValue))
{
if (!elfentable.ContainsKey(columnName))
{
// If the column name isn't in the dictionary yet, add it with a new collection
elfentable[columnName] = new ObservableCollection<Filter>();
}
var filters = elfentable[columnName];
if (!filters.Any(f => f.Title == columnValue))
{
// If the filter isn't in the collection yet, add it
filters.Add(new Filter { Title = columnValue, IsChecked = true, FilterColor = false }) ;
}
}
}
}
elfenviewsource = new CollectionViewSource();
elfenviewsource.Source = elfenload.Pumps;
//FilterDatabases();
//elfendatagrid.ItemsSource = elfenviewsource.View;
//elfenviewsource.Filter += Elfenviewsource_Filter;
}
public void FilterTextChanged(string filterText)
{
var searchQuery = filterText;
FilterView.Filter = item =>
{
var filter = item as Filter;
if (filter == null) return false;
return filter.Title.IndexOf(searchQuery, StringComparison.OrdinalIgnoreCase) >= 0;
};
}
public void Search(object parameter)
{
var searchQuery = parameter as string;
FilterView.Filter = item =>
{
var filter = item as Filter;
if (filter == null) return false;
return filter.Title.Contains(searchQuery);
};
}
public Dictionary<string, bool> IsFilterApplied
{
get
{
Dictionary<string, bool> results = new Dictionary<string, bool>();
foreach (var key in ColumnFilters.Keys)
{
results[key] = IsFilterAppliedToColumn(key);
}
return results;
}
}
private ICommand _isFilterAppliedCommand;
public ICommand IsFilterAppliedCommand
{
get
{
if (_isFilterAppliedCommand == null)
{
_isFilterAppliedCommand = new RelayCommand(
param => this.IsFilterAppliedToColumn(param as string),
param => param is string);
}
return _isFilterAppliedCommand;
}
}
public bool IsFilterAppliedToColumn(string columnName)
{
return ColumnFilters.ContainsKey(columnName) && ColumnFilters[columnName];
}
public void ApplyFilter(object obj)
{
FilterDatabases();
// Update ColumnFilters after filtering the databases
// Check if CurrentFilteredColumn is not null or an empty string
if (string.IsNullOrEmpty(CurrentFilteredColumn))
{
throw new InvalidOperationException("CurrentFilteredColumn cannot be null or an empty string");
}
// You can use CurrentFilteredColumn wherever you need the column name
// Update ColumnFilters after filtering the databases
foreach (var key in elfentable.Keys)
{
ColumnFilters[key] = elfentable[key].Any(filter => filter.IsChecked);
if (ColumnFilters[key])
{
// if filter is applied to the column, change FilterColor to true
foreach (var filter in elfentable[key])
{
filter.FilterColor = true;
}
}
}
// Checking if a filter is applied to the current column
if (IsFilterAppliedToColumn(CurrentFilteredColumn))
{
FilteredColumnName = CurrentFilteredColumn;
}
else
{
FilteredColumnName = null; // set it to null if filter is removed
}
//CurrentFilteredColumn = obj.ToString();
OnPropertyChanged(nameof(ColumnFilters));
OnPropertyChanged(nameof(CurrentFilteredColumn));
}
public void FilterDatabases()
{
FilteredDatabases.Clear();
foreach (var db in _databases)
{
if (ShouldAccept(db))
{
FilteredDatabases.Add(db);
}
}
//foreach (var key in elfentable.Keys)
//{
// ColumnFilters[key] = elfentable[key].Any(filter => filter.IsChecked);
//}
OnPropertyChanged("FiltersApplied");
OnPropertyChanged(nameof(FilteredDatabases));
}
private bool ShouldAccept(LoadDatabases ld)
{
string ColName = "";
int count;
try
{
foreach (var item in ld.GetType().GetProperties())
{
ColName = item.Name;
var propertyValue = ld.GetType().GetProperty(ColName).GetValue(ld, null);
if (propertyValue == null) continue; // if value is null, go to next iteration
string value = propertyValue.ToString();
if (elfentable.ContainsKey(ColName))
{
ObservableCollection<Filter> elfencurrent;
elfentable.TryGetValue(ColName, out elfencurrent);
count = 0;
if (elfencurrent != null)
{
count = elfencurrent.Where(w => w.IsChecked).Count(w => w.Title == value);
if (count == 0)
{
return false;
}
}
}
}
}
catch
{
return true;
}
return true;
}
public void Filter(object paramater)
{
IsPopupOpen = true;
string colName = paramater as string;
CurrentFilteredColumn = colName;
if (elfentable.ContainsKey(colName))
{
elfentable.TryGetValue(colName, out var elfencurrent);
CurrentFilters.Clear();
foreach (var item in elfencurrent)
{
CurrentFilters.Add(item);
}
}
// Reset FilterColor to false for all filters when filter is removed
foreach (var filter in CurrentFilters)
{
filter.FilterColor = false;
}
FilterView = CollectionViewSource.GetDefaultView(CurrentFilters);
OnPropertyChanged(nameof(FilterView));
OnPropertyChanged(nameof(CurrentFilteredColumn));
}
the filter Class,
private bool _Ischecked;
public bool IsChecked
{
get { return _Ischecked; }
set
{
_Ischecked = value;
OnPropertyChanged(nameof(IsChecked));
}
}
private string _Title;
public string Title
{
get { return _Title; }
set
{
_Title = value;
OnPropertyChanged(nameof(Title));
}
}
private bool _FilterColor = false;
public bool FilterColor
{
get { return _FilterColor; }
set
{
_FilterColor = value;
OnPropertyChanged(nameof(FilterColor));
}
}
and finally the xaml code,
<DataGrid RowStyle="{DynamicResource elfenliedtopfan5_RowStyle}" Style="{DynamicResource DataGridElfenStyleMain}"
x:Name="elfendatagrid"
IsReadOnly="True"
ItemsSource="{Binding FilteredDatabases}"
Grid.Row="1">
<DataGrid.Resources>
<Style TargetType="DataGridColumnHeader">
<Setter Property="Background">
<Setter.Value>
<MultiBinding Converter="{StaticResource ColumnFilterToBrushConverter}">
<Binding Path="Content" RelativeSource="{RelativeSource Self}"/>
<Binding Path="DataContext.ColumnFilters" RelativeSource="{RelativeSource AncestorType=DataGrid}"/>
</MultiBinding>
</Setter.Value>
</Setter>
<Setter Property="Foreground" Value="White"/>
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock x:Name="tbHeader" Text="{Binding}" Margin="10,5"/>
<Button x:Name="btnFilter"
Content="[x]"
Command="{Binding DataContext.FilterCommand, RelativeSource={RelativeSource AncestorType=DataGrid}}"
CommandParameter="{Binding Content, RelativeSource={RelativeSource AncestorType=DataGridColumnHeader}}">
<Button.Style>
<Style TargetType="Button">
<Setter Property="Background" Value="Transparent"/>
<Style.Triggers>
<DataTrigger Value="True">
<DataTrigger.Binding>
<MultiBinding Converter="{StaticResource ColumnFilterToBrushConverter}">
<Binding Path="Content" RelativeSource="{RelativeSource AncestorType=DataGridColumnHeader}"/>
<Binding Path="DataContext.ColumnFilters" RelativeSource="{RelativeSource AncestorType=DataGrid}"/>
</MultiBinding>
</DataTrigger.Binding>
<Setter Property="Background" Value="Orange" />
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
</StackPanel>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</DataGrid.Resources>
</DataGrid>
<Popup x:Name="popExcel" Width="300" Height="300" Placement="Bottom" StaysOpen="False" IsOpen="{Binding IsPopupOpen}">
<Border Background="Gray" BorderBrush="Gray" >
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBox x:Name="tbFilter" Grid.Row="0" Margin="10">
<i:Interaction.Triggers>
<i:EventTrigger EventName="TextChanged">
<i:InvokeCommandAction Command="{Binding FilterTextChangedCommand}" CommandParameter="{Binding Text, ElementName=tbFilter}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</TextBox>
<Separator Grid.Row="0"
VerticalAlignment="Bottom"
Margin="10,0"
Height="3">
</Separator>
<ListBox x:Name="lbFilter"
Grid.Row="1"
Margin="10"
ItemsSource="{Binding FilterView}">
<ListBox.ItemTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding IsChecked}" Content="{Binding Title}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<Button Grid.Row="2"
Content="Apply Filter"
Margin="10"
x:Name="ApplyFilter"
Command="{Binding DataContext.ApplyFilterCommand, RelativeSource={RelativeSource AncestorType=Popup}}"
CommandParameter="{Binding ElementName=popExcel, Path=Uid}">
</Button>
</Grid>
</Border>
</Popup>
and the converter is
public class ColumnFilterToBrushConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
if (values.Length != 2)
return Brushes.Transparent;
var columnName = values[0] as string;
var columnFilters = values[1] as Dictionary<string, bool>;
if (columnName == null || columnFilters == null)
return Brushes.Transparent;
if (columnFilters.ContainsKey(columnName) && columnFilters[columnName])
return Brushes.Orange;
return Brushes.Transparent;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
honestly, any help would be much appreciated
been trying to get this to work for a week but just cant get it to act on the colum and button,
kind regards,
elfenliedtopfan5
i have zipped up the project file for viewing only thing i cant include is the database itself as its real data but project code is here,
https://www.mediafire.com/file/fmx84oixiqlx7iw/DatabaseFiltering.zip/file
this is the full project.
Hi,@mion shion . For the issue of trigger background of button in DataGridColumnHeader, you could use the following code.
<DataGrid.Resources>
<Style TargetType="DataGridColumnHeader">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock x:Name="tbHeader" Text="{Binding}" Margin="10,5"/>
<Button x:Name="btnFilter" Content="[x]" Width="30"
Command="{Binding DataContext.FilterCommand, RelativeSource={RelativeSource AncestorType=DataGrid}}"
CommandParameter="{Binding Content, RelativeSource={RelativeSource AncestorType=DataGridColumnHeader}}">
<Button.Style>
<Style TargetType="Button">
<Setter Property="Background">
<Setter.Value>
<MultiBinding Converter="{StaticResource ColumnFilterToBrushConverter}">
<Binding Path="Content" RelativeSource="{RelativeSource AncestorType=DataGridColumnHeader}"/>
<Binding Path="DataContext.ColumnFilters" RelativeSource="{RelativeSource AncestorType=DataGrid}"/>
</MultiBinding>
</Setter.Value>
</Setter>
<Style.Triggers>
<DataTrigger Value="True">
<DataTrigger.Binding>
<MultiBinding Converter="{StaticResource ColumnFilterToBrushConverter}">
<Binding Path="Content" RelativeSource="{RelativeSource AncestorType=DataGridColumnHeader}"/>
<Binding Path="DataContext.ColumnFilters" RelativeSource="{RelativeSource AncestorType=DataGrid}"/>
</MultiBinding>
</DataTrigger.Binding>
<Setter Property="Background" Value="Orange" />
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
</StackPanel>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</DataGrid.Resources>
The result:
If the response is helpful, please click "Accept Answer" and upvote it.
Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.