none
WPF datagrid bound to dataview (filtering ivalueconverter return) RRS feed

  • Question

  • Good morning, I am attempting to resolve an outstanding issue I have with a datagrid which is bound to a dataview. What I have included in my datagrid is a column header textbox for the user to filter the contents. This filtering works as expected on values which are directly bound however doesn't work on values which use a ivalueconverter. Is there a way to filter on the ivalueconverted value (clear text) rather than filtering on the underlying values (guids)?

    Datagrid xml snippet

    <DataGrid ItemsSource="{Binding dataview, UpdateSourceTrigger=PropertyChanged, NotifyOnSourceUpdated=True}">
    
    <DataGridTextColumn Width="*" Binding="{Binding Location,UpdateSourceTrigger=PropertyChanged, Converter={StaticResource LocationSysIdToNameConverter}}">
                                <DataGridTextColumn.HeaderTemplate>
                                    <DataTemplate>
                                        <StackPanel Orientation="Vertical">
                                            <Label Content="Location"/>
                                            <TextBox x:Name="textboxLocationFilter" TextChanged="TextboxFilter_TextChanged" IsEnabled="False"/>
                                        </StackPanel>
                                    </DataTemplate>
                                </DataGridTextColumn.HeaderTemplate>
                            </DataGridTextColumn>
    </DataGrid>

    *The above attempts to filter on the guid rather than the displayed and returned value.

    Textchanged filter:

            private void TextboxFilter_TextChanged(object sender, TextChangedEventArgs e)
            {
                string thefilter;
                
                // Get textboxes
                TextBox locationFilter = FindChild<TextBox>(datagrid, "textboxLocationFilter");
                
    
                // Build filter
                List<string> allParams = new List<string>
                {
                    "location like '%" + locationFilter.Text + "%'"
                };
    
                // Create final filter
                string finalFilter = string.Join(" and ", allParams);
    
                // Filter dataview
                MainWindow.ViewModel.datagridview.RowFilter = finalFilter;
            }

    I am aware I "could" add an additional property to my bound dataview however am attempting to avoid doing this as I would have to in fact add 4 or 5 of these, I am only showing the code for 1 column here but there are around 4 which all do the same thing, use an ivalueconverter.


    • Edited by Tithras Friday, January 17, 2020 10:15 AM Added textchanged
    Friday, January 17, 2020 10:11 AM

All replies

  • Hi,

    Is this what you want?

     <Window.Resources>
            <local:LocationSysIdToNameConverter x:Key="LocationSysIdToNameConverter"/>
        </Window.Resources>
        <Grid>
            <DataGrid Name="dg1" AutoGenerateColumns="False" ItemsSource="{Binding dataview, UpdateSourceTrigger=PropertyChanged, NotifyOnSourceUpdated=True}" >
                <DataGrid.Columns>
                
                    <DataGridTextColumn Width="*" Binding="{Binding Location,UpdateSourceTrigger=PropertyChanged, Converter={StaticResource LocationSysIdToNameConverter}}">
                    <DataGridTextColumn.HeaderTemplate>
                        <DataTemplate>
                            <StackPanel Orientation="Vertical">
                                <Label Content="Location"/>
                                <TextBox x:Name="textboxLocationFilter" TextChanged="TextboxFilter_TextChanged" />
                            </StackPanel>
                        </DataTemplate>
                    </DataGridTextColumn.HeaderTemplate>
                </DataGridTextColumn>
                </DataGrid.Columns>
              
    
            </DataGrid>
        </Grid>
      public partial class MainWindow : Window
        {
            MyClass mc = new MyClass();
            public MainWindow()
            {
                
                InitializeComponent();
             
                this.dg1.DataContext = mc;
    
               
            }
            public static T FindChild<T>(DependencyObject root, string name) where T : DependencyObject
            {
                if (root == null)
                    return null;
    
                T founded = null;
    
                for (int j = 0; j < VisualTreeHelper.GetChildrenCount(root); j++)
                {
                    DependencyObject d = VisualTreeHelper.GetChild(root, j);
                    T childType = d as T;
                    if (childType == null || ((d is FrameworkElement) && (d as FrameworkElement).Name != name))
                    {
                        founded = FindChild<T>(d, name);
                        if (founded != null)
                            break;
                    }
                    else
                    {
                        founded = childType;
                        break;
                    }
                }
                return founded;
            }
            private void TextboxFilter_TextChanged(object sender, TextChangedEventArgs e)
            {
                var cvs = CollectionViewSource.GetDefaultView(dg1.ItemsSource);
                if (cvs != null && cvs.CanFilter)
                {
                    cvs.Filter = OnFilterApplied;
                }
            }
            private bool OnFilterApplied(object obj)
            {
                TextBox locationFilter = FindChild<TextBox>(dg1, "textboxLocationFilter");
                if (obj is Student)
                {
                    var text = locationFilter.Text.ToLower();
                    return (obj as Student).Location.ToString().Contains(text);
                       
                }
                return false;
            }      
        }
        public class LocationSysIdToNameConverter : IValueConverter
        {
            public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
            {
                int temp = (int)value;
                switch (temp)
                {
                    case 1:
                        return "Location1";
    
                    case 2:
                        return "Location2";
    
                    case 3:
                        return "Location3";
    
    
                    default:
                        return " ";
                }
    
            }
    
    
            public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
            {
                throw new NotImplementedException();
            }
        }
        public class MyClass
        {
            private ObservableCollection<Student> _dataview;
            public ObservableCollection<Student> dataview
            {
                get { return _dataview; }
                set { _dataview = value; }
            }
    
          
            public MyClass()
            {
                dataview = new ObservableCollection<Student>();
                dataview.Add(new Student() { Location=1 });
                dataview.Add(new Student() { Location=2});
                dataview.Add(new Student() { Location=3});
    
             
            }
        }
        public class Student : INotifyPropertyChanged
        {
            public event PropertyChangedEventHandler PropertyChanged;
         
            private int _Location;
    
            public int Location
            {
                get
                {
                    return _Location;
                }
                set
                {
                   _Location = value;
                    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Location"));
                }
            }
        }


    Best Regards,

    Alex


    MSDN Community Support Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.


    Monday, January 20, 2020 5:03 AM
    Moderator