Changing button colur on colum button when filter is applied. wpf

mion shion 241 Reputation points
2023-05-21T19:48:22.0066667+00:00

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

programproblem1

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

Windows Presentation Foundation
Windows Presentation Foundation
A part of the .NET Framework that provides a unified programming model for building line-of-business desktop applications on Windows.
2,679 questions
{count} votes

2 answers

Sort by: Most helpful
  1. mion shion 241 Reputation points
    2023-05-23T20:50:56.3133333+00:00

    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.


  2. Hui Liu-MSFT 40,666 Reputation points Microsoft Vendor
    2023-05-24T03:11:54.67+00:00

    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:

    9


    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.