2016-10-27 2 views
0

Das von mir angestrebte Verhalten ist: Ich habe ein Datenraster mit einer einzelnen Spalte. Es ist an eine Liste von Elementen gebunden, die verschiedene Informationen über eine Person enthalten. Wenn diese Option nicht ausgewählt ist, wird in der Zeile einfach der Name der Person angezeigt. Wenn die Zeile ausgewählt ist (d.h. angeklickt wurde), sollte ich mehr Informationen über die Person zeigen.Ändern des DataGrid-Zelleninhalts/der Vorlage für die Zeilenauswahl

Mein erster Versuch war, eine DataGridTemplateColumn zu verwenden, wo das CellTemplate ein ContentControl ist. Der Stil des ContentControls wird durch den Status der ausgewählten Zeile bestimmt.

Mein Stil:

<DataTemplate x:Key="NotSelectedTemplate"> 
    <TextBlock Text="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ContentControl}, Path=DataContext.PatientName.FormattedName, Mode=OneWay, BindsDirectlyToSource=True, UpdateSourceTrigger=PropertyChanged}" /> 
</DataTemplate> 

<DataTemplate x:Key="SelectedTemplate"> 
    <TextBlock Height="60" Text="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ContentControl}, Path=DataContext.PatientName.FormattedName, Mode=OneWay, BindsDirectlyToSource=True, UpdateSourceTrigger=PropertyChanged}" /> 
    </DataTemplate> 

<Style x:Key="SelectableContentStyle" TargetType="{x:Type ContentControl}"> 
    <Style.Triggers> 
     <DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGridRow}}, Path=IsSelected}" Value="False"> 
      <Setter Property="ContentTemplate" Value="{StaticResource NotSelectedTemplate}" /> 
     </DataTrigger> 
     <DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGridRow}}, Path=IsSelected}" Value="True"> 
      <Setter Property="ContentTemplate" Value="{StaticResource SelectedTemplate}" /> 
     </DataTrigger> 
    </Style.Triggers> 
</Style> 

Meine Datagrid Spalten:

<DataGrid.Columns> 
    <DataGridTemplateColumn Width="*"> 
     <DataGridTemplateColumn.CellTemplate> 
      <DataTemplate> 
       <ContentControl Style="{StaticResource SelectableContentStyle}" /> 
      </DataTemplate> 
     </DataGridTemplateColumn.CellTemplate> 
    </DataGridTemplateColumn> 
</DataGrid.Columns> 

Dieser Ansatz arbeitet jedoch in jedem Datatemplate die Bindung ist ziemlich hässlich. Ich bin relativ unerfahren bei WPF, also bin ich mir sicher, dass es einen viel besseren Weg geben muss, dies zu implementieren.

Grundsätzlich 1) Gibt es eine bessere Möglichkeit, dieses Verhalten zu erreichen? 2) Gibt es eine bessere Möglichkeit, an das DataTemplate zu binden, damit ich RelativeSources nicht jedes Mal jage, wenn ich auf eine Eigenschaft zugreifen möchte?

+0

Das ist so ziemlich wie ich es tun würde. –

+0

Ich verstehe. Die Bindungen in den DateTemplates sind jedoch sehr hässlich. Wenn man bedenkt, dass ich 5+ Textblock-/Eigenschaftsbindungen haben werde, hatte ich gehofft, dass es einen saubereren Weg gab, die Bindung in jedem DataTemplate zu machen. – krames

Antwort

0

Sie könnten einen Vorlagenselektor für die ContentTemplateProperty implementieren, die zwei Vorlagen als Eigenschaften hat und eine Boolesche Eigenschaft hat, um zwischen ihnen zu wechseln.

Die schlechte Nachricht ist, dass die Basisklasse (DataTemplateSelector) kein Abhängigkeitsobjekt ist und daher keine Bindung für Ihre Flag-Eigenschaft unterstützt. In diesen Fällen arbeite ich daran, indem ich eine Config -Eigenschaft hinzufüge, die eine Instanz einer benutzerdefinierten Klasse enthält, die Sie dann zu einer Unterklasse von DependencyObject machen und dort Abhängigkeitseigenschaften definieren können. Dies wird natürlich Ihren Code erneut aufblasen, und Bindungen haben Einschränkungen, weil formell die Bindungsbereiche brechen.


Eine weitere Option könnte die beiden Vorlagen im SelectableContentStyle über DynamicResource zu verweisen sein, so brauchen Sie nur, dass DataTrigger Schalter einmal zu schreiben und nur die beiden Vorlagen in den Ressourcen innerhalb der einzelnen DataTemplates definieren.

Siehe this answer für ein Beispiel.

Verwandte Themen