This project has moved. For the latest updates, please go here.

How to Trigger and handle TextChanged event from Text Box within DataGridColumnHeader in style Resource Dictionary

Apr 21, 2013 at 11:27 AM
Hi,
I asked this question in several places with no answer, so i hope to find the answer here.
I develop Prism+MEF application based on WPF+MVVM, where there are many DataGrids so i build DataGridStyle to be applied for all DataGrids in all modules. The style add Filter Text Box in the Columns Headers, and i used MVVM Light EventToCommand to trigger TextChanged event when the Text Box text is changed like this: (this code exist in DataGridStyle Resource Dictionary)
 <!--Filter Text Box-->
                            <TextBox x:Name="filterTextBox" HorizontalAlignment="Right" 
                                         MinWidth="25" Height="Auto" OpacityMask="Black" Visibility="Collapsed" 
                                         Text="" 
                                         TextWrapping="Wrap" Grid.Column="0" Grid.ColumnSpan="1">
                                         
                                <i:Interaction.Triggers>
                                    <i:EventTrigger EventName="TextChanged">

                                        <cmd:EventToCommand  Command="{Binding local:FilteringDataGrid.HandleTextChanged}"
                                                             PassEventArgsToCommand="True"
                                                             CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type TextBox}}, Path=Name}"/>
                                       
                                    </i:EventTrigger>
                                </i:Interaction.Triggers>
                                
                            </TextBox>
Then i handled the TextChangedCommand in FilteringDataGrid class using Attached Behavior :
#region TextChangedCommand----------------------------------------------------------------------------------------------

        static ICommand command; //1

        public static ICommand GetHandleTextChanged(TextBox target)
        {
            
            return (ICommand)target.GetValue(HandleTextChangedProperty);

        }

        public static void SetHandleTextChanged(TextBox target, ICommand value)
        {
            
            target.SetValue(FilteringDataGrid.HandleTextChangedProperty, value);

        }

       
        public static readonly DependencyProperty HandleTextChangedProperty =
            DependencyProperty.RegisterAttached("HandleTextChanged",
                                                 typeof(ICommand),
                                                 typeof(FilteringDataGrid),
                                                 new UIPropertyMetadata(new PropertyChangedCallback(TextChangedChanged)));
        

        static void TextChangedChanged(DependencyObject target, DependencyPropertyChangedEventArgs e)
        {
           
            TextBox element = target as TextBox;

            if (element != null)
            {
                if (e.NewValue != null)
                {
                    element.TextChanged += Element_TextChanged;
                }
                else
                {
                    element.TextChanged -= Element_TextChanged;
                }
            }

        }
        
        static void Element_TextChanged(object sender, TextChangedEventArgs e)
        {
            
            // Get the textbox
            TextBox filterTextBox = e.OriginalSource as TextBox;

            // Get the header of the textbox
            DataGridColumnHeader header = TryFindParent<DataGridColumnHeader>(filterTextBox);
            if (header != null)
            {
                //UpdateFilter(this.filterTextBox, header);
                //this.ApplyFilters();
            }
        }


        #endregion
And the View that contains the Grid:
 <DataGrid  ItemsSource="{Binding Subsystems,Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                   SelectedItem="{Binding Path=SelectedSubsystem, Mode=TwoWay}"                        
                   Name="SubsystemAllDataGrid"              
                   Style="{StaticResource DataGridStyle}"
                   
                   Grid.Row="2">
            

            <DataGrid.Columns>
                <DataGridTextColumn Header="Serial" Binding="{Binding Path=Serial, Mode=TwoWay}"></DataGridTextColumn>
                <DataGridTextColumn Header="Type" Binding="{Binding Path=Type, Mode=TwoWay}"></DataGridTextColumn>
                <DataGridTextColumn Header="System" Binding="{Binding Path=System, Mode=TwoWay}"></DataGridTextColumn>
                <DataGridTextColumn Header="SubsystemNo"  Binding="{Binding Path=SubsystemNo, Mode=TwoWay}"></DataGridTextColumn>
                <DataGridTextColumn Header="Description" Binding="{Binding Path=Description, Mode=TwoWay}"></DataGridTextColumn>
                <DataGridTextColumn Header="Scope" Binding="{Binding Path=Scope, Mode=TwoWay}"></DataGridTextColumn>
                <DataGridTextColumn Header="Area" Binding="{Binding Path=Area, Mode=TwoWay}"></DataGridTextColumn>
                <DataGridTextColumn Header="Priority" Binding="{Binding Path=Priority, Mode=TwoWay}"></DataGridTextColumn>
                <DataGridTextColumn Header="DossierLocation" Binding="{Binding Path=DossierLocation, Mode=TwoWay}"></DataGridTextColumn>
                <DataGridTextColumn Header="Parts" Binding="{Binding Path=Parts, Mode=TwoWay}"></DataGridTextColumn>
                <DataGridTextColumn Header="Status" Binding="{Binding Path=Status, Mode=TwoWay}"></DataGridTextColumn>
                <DataGridTextColumn Header="StatusDate" Binding="{Binding Path=StatusDate, Mode=TwoWay}"></DataGridTextColumn>
                <DataGridTextColumn Header="MCDate" Binding="{Binding Path=MCDate, Mode=TwoWay}"></DataGridTextColumn>
                <DataGridTextColumn Header="PlnMCDate" Binding="{Binding Path=PlnMCDate, Mode=TwoWay}"></DataGridTextColumn>
                <DataGridTextColumn Header="Remark" Binding="{Binding Path=Remark, Mode=TwoWay}"></DataGridTextColumn>

            </DataGrid.Columns>

        </DataGrid>

The problems are: When i enter filter text in the text box in one of the columns headers of the data grid nothing happen and break points at following points not hit:

1-GetHandleTextChangedand SetHandleTextChanged

2-The TextChangedChanged() method. (not Called)
The only breakpoint hit @ Attached Property statement 

i'm new to wpf so i'm sure there are faults in WPF or C# code..., so please help me fixing these faults.

Note: i don't use code behind.

Thanks in advance