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,760 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 48,256 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.


Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.