2016-08-09 121 views
2

Nachdem ich einige Tage versucht habe, habe ich mein Projekt auf das Minimum reduziert, um es hier an meine Frage anzuhängen.DataGrid Spaltenüberschrift mit Filterbox Bindungsfehler

Ich möchte ein Textfilterfeld zu meinem WPF-Datagrid-Header hinzufügen. Aber ich bekomme diese Fehlermeldung:

System.Windows.Data Error: 40 : BindingExpression path error: 'TextFilterData' property not found on 'object' ''DataGridColumnHeader' (Name='PART_FillerColumnHeader')'. BindingExpression:Path=TextFilterData; DataItem='DataGridColumnHeader' (Name='PART_FillerColumnHeader'); target element is 'TextBox' (Name='PART_TextFilter'); target property is 'Text' (type 'String') 
System.Windows.Data Error: 40 : BindingExpression path error: 'TextFilterData' property not found on 'object' ''DataGridColumnHeader' (Name='')'. BindingExpression:Path=TextFilterData; DataItem='DataGridColumnHeader' (Name=''); target element is 'TextBox' (Name='PART_TextFilter'); target property is 'Text' (type 'String') 

Die Datagrid in meiner Anwendung:

<Grid> 
    <local:MyDataGrid x:Name="myDataGrid"> 
     <DataGrid.Columns> 
      <DataGridTextColumn Header="ID" Width="64" 
           Binding="{Binding Path=id, Mode=OneWay, UpdateSourceTrigger=PropertyChanged, FallbackValue=''}" 
           local:DataGridColumnExtensions.TextFilterData="{Binding Path=FilterId, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"> 
       <DataGridTextColumn.HeaderStyle> 
        <Style TargetType="DataGridColumnHeader" BasedOn="{StaticResource {x:Type DataGridColumnHeader}}"> 
         <Setter Property="ToolTip" Value="The ID of the person"/> 
        </Style> 
       </DataGridTextColumn.HeaderStyle> 
      </DataGridTextColumn> 

      <!-- The filter data will be replaced by property binding in the real application. Here I'm using a fix value for the sake of simplicity --> 
      <DataGridTextColumn Header="Name" Width="400" 
           Binding="{Binding Path=name, Mode=OneWay, UpdateSourceTrigger=PropertyChanged, FallbackValue=''}" 
           local:DataGridColumnExtensions.TextFilterData="{Binding Path=FilterName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"> 
       <DataGridTextColumn.HeaderStyle> 
        <Style TargetType="DataGridColumnHeader" BasedOn="{StaticResource {x:Type DataGridColumnHeader}}"> 
         <Setter Property="ToolTip" Value="The name of the person"/> 
        </Style> 
       </DataGridTextColumn.HeaderStyle> 
      </DataGridTextColumn> 
     </DataGrid.Columns> 
    </local:MyDataGrid> 
</Grid> 

ich eine Erweiterungsklasse bin mit der Abhängigkeitseigenschaft für den Textfilter Inhalt

public class DataGridColumnExtensions 
{ 
    public static readonly DependencyProperty TextFilterDataProperty = DependencyProperty.RegisterAttached("TextFilterData", typeof(string), typeof(DataGridColumn), new FrameworkPropertyMetadata(String.Empty)); 
    public static string GetTextFilterData(DependencyObject target) 
    { 
     return (string)target.GetValue(TextFilterDataProperty); 
    } 
    public static void SetTextFilterData(DependencyObject target, string value) 
    { 
     target.SetValue(TextFilterDataProperty, value); 
    } 
} 
erstellen

Und hier ist der Datagrid-Stil, den ich verwende. Ich habe versucht, alles zu entfernen, was der Einfachheit halber nicht benötigt wird.

<Style TargetType="{x:Type DataGridColumnHeader}"> 
    <Setter Property="SnapsToDevicePixels" Value="True" /> 
    <Setter Property="Foreground" Value="White" /> 
    <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="{x:Type DataGridColumnHeader}"> 
       <Grid> 
        <Grid.ColumnDefinitions> 
         <ColumnDefinition Width="*" /> 
         <ColumnDefinition Width="Auto" /> 
        </Grid.ColumnDefinitions> 
        <Grid.RowDefinitions> 
         <RowDefinition Height="*"/> 
         <RowDefinition Height="Auto"/> 
        </Grid.RowDefinitions> 
        <Border x:Name="BackgroundBorder" BorderThickness="0,1,0,1" Background="Gray" BorderBrush="DarkGray" Grid.ColumnSpan="2" /> 
        <ContentPresenter Margin="3" VerticalAlignment="Center" /> 
        <Path x:Name="SortArrow" Visibility="Collapsed" Data="M0,0 L1,0 0.5,1 z" Stretch="Fill" Grid.Column="1" Width="8" Height="6" Fill="White" Margin="0,0,8,0" VerticalAlignment="Center" RenderTransformOrigin="0.5,0.5" /> 
        <TextBox x:Name="PART_TextFilter" 
          Grid.Row="1" Margin="1,0,1,4" 
          Text="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGridColumnHeader}}, Path=Column.TextFilterData, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/> 
        <Thumb x:Name="PART_LeftHeaderGripper" HorizontalAlignment="Left" Style="{StaticResource Style_HeaderGripper}"/> 
        <Thumb x:Name="PART_RightHeaderGripper" HorizontalAlignment="Right" Style="{StaticResource Style_HeaderGripper}"/> 
       </Grid> 
       <ControlTemplate.Triggers> 
        <Trigger Property="SortDirection" Value="{x:Null}"> 
         <Setter TargetName="BackgroundBorder" Property="Background" Value="Transparent" /> 
         <Setter TargetName="BackgroundBorder" Property="BorderBrush" Value="Transparent" /> 
        </Trigger> 
        <Trigger Property="IsMouseOver" Value="True"> 
         <Setter TargetName="BackgroundBorder" Property="Background" Value="LightGray" /> 
         <Setter TargetName="BackgroundBorder" Property="BorderBrush" Value="Gray" /> 
        </Trigger> 
        <Trigger Property="SortDirection" Value="Ascending"> 
         <Setter TargetName="SortArrow" Property="Visibility" Value="Visible" /> 
         <Setter TargetName="SortArrow" Property="RenderTransform"> 
          <Setter.Value> 
           <RotateTransform Angle="180" /> 
          </Setter.Value> 
         </Setter> 
        </Trigger> 
        <Trigger Property="SortDirection" Value="Descending"> 
         <Setter TargetName="SortArrow" Property="Visibility" Value="Visible" /> 
        </Trigger> 
       </ControlTemplate.Triggers> 
      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
</Style> 

<Style TargetType="{x:Type local:MyDataGrid}"> 
    <Setter Property="SnapsToDevicePixels" Value="True" /> 
    <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="{x:Type local:MyDataGrid}"> 
       <Border Background="{TemplateBinding Background}"> 
        <ScrollViewer Focusable="false" Name="DG_ScrollViewer"> 
         <ScrollViewer.Template> 
          <ControlTemplate TargetType="{x:Type ScrollViewer}"> 
           <Grid> 
            <Grid.RowDefinitions> 
             <RowDefinition Height="Auto"/> 
             <RowDefinition Height="*"/> 
             <RowDefinition Height="Auto"/> 
            </Grid.RowDefinitions> 
            <Grid.ColumnDefinitions> 
             <ColumnDefinition Width="Auto"/> 
             <ColumnDefinition Width="*"/> 
             <ColumnDefinition Width="Auto"/> 
            </Grid.ColumnDefinitions> 
            <Border Grid.ColumnSpan="3" Background="Gray" BorderBrush="DarkGray" BorderThickness="0,1" /> 
            <Button Command="{x:Static DataGrid.SelectAllCommand}" Width="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}, Path=RowHeaderActualWidth}" Focusable="false" OverridesDefaultStyle="True"/> 
            <DataGridColumnHeadersPresenter Grid.Column="1"       
                    Visibility="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}, 
                         Path=HeadersVisibility, 
                         Converter={x:Static DataGrid.HeadersVisibilityConverter}, 
                         ConverterParameter={x:Static DataGridHeadersVisibility.Column}}"/> 
            <ScrollContentPresenter Grid.Row="1" Grid.ColumnSpan="2" CanContentScroll="{TemplateBinding CanContentScroll}" /> 
           </Grid> 
          </ControlTemplate> 
         </ScrollViewer.Template> 
         <ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" /> 
        </ScrollViewer> 
       </Border> 
      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
    <Style.Triggers> 
     <Trigger Property="IsGrouping" Value="true"> 
      <Setter Property="ScrollViewer.CanContentScroll" Value="false"/> 
     </Trigger> 
    </Style.Triggers> 
</Style> 

Was fehlt, um die Bindung des Filterinhalts zu erhalten? Jede Hilfe wird sehr geschätzt.


2016-08-10: Update mit ersten fix

Antwort

1

Im Header-Control, Sie verwenden RelativeSource Self innerhalb des TextBox

<TextBox x:Name="PART_TextFilter" 
    ... 
    Text="{Binding RelativeSource={RelativeSource Self}, Path=TextFilterData, ...}"/> 

Die Fehlermeldung besagt, gibt es keine TextFilterData Eigenschaft auf diesem TextBox.

Versuchen

Text="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGridColumnHeader}}, 
       Path=Column.TextFilterData, ...}"/> 
+0

Ja, das war auch meine ursprüngliche Version, aber ich änderte es, während ich um spielte. Tut mir leid, dass ich es nicht zurück geändert habe, weil 'AncestorType = {x: Type DataGridColumnHeader}} mehr Sinn macht. Ich habe meine Frage oben aktualisiert, aber es funktioniert immer noch nicht. – Carpi

+0

@Carpi Kein Problem, hast du bemerkt, dass ich den Pfad auch geändert habe? Die Attached-Eigenschaft befindet sich in der DataGridColumn und nicht im DataGridColumnHeader. – Funk

+0

Cool, das hat mein Problem gelöst. Vielen Dank für Ihre großartige Hilfe: o) – Carpi