2009-07-29 4 views
0

Ich frage mich, ob es möglich war, das Styling einer Spalte in einem WPF DataGrid je nach Art des Elements in der ItemsSource-Auflistung zu ändern.Unterschiedliche Zellenstyling in einem WPF DataGrid je nach Datentyp in der ItemsSource

Ich habe ein Wpf DataGrid aus dem WPF Toolkit. Die einzelnen Zeilen im Raster sollten abhängig vom Typ des Elements aus der ItemsSource-Auflistung gestaltet werden. Daher haben alle Elemente denselben Basisklassentyp, aber die Spalten einiger abgeleiteter Typen sollten eine andere Stilisierung erhalten.

Ist das möglich?

Danke :-)

Antwort

2

Ja, es möglich ist, sie auf verschiedene Weise zu tun. Die eine, die ich gehen würde, ist das Schreiben eines eigenen benutzerdefinierten "Typswitch" -Konverters, der je nach Art der Eingabe einen Wert auswählt. Wie folgt aus:

public class TypeSwitchConverter : Dictionary<Type, object>, IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, .CultureInfo culture) 
    { 
     foreach (var mapping in this) 
     { 
      if (mapping.Key.IsAssignableFrom(value.GetType())) 
      { 
       return mapping.Value; 
      } 
     } 

     return null; 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     throw new NotImplementedException(); 
    } 
} 

Und dann eine Bindung für die Style der Top-Level-Element in Vorlage für Ihr Handy nutzen, und verwenden Sie die oben Konverter für die je nach Bedarf zu binden. Hier ist ein vereinfachtes Beispiel, dass Arteinzelteile in einem ListBox mit ihm:

<ListBox ItemsSource="{Binding}"> 
     <ListBox.ItemTemplate> 
      <DataTemplate> 
       <TextBlock Text="{Binding}"> 
        <TextBlock.Style> 
         <Binding> 
          <Binding.Converter> 
           <my:TypeSwitchConverter> 
            <Style x:Key="{x:Type cor:Int32}" TargetType="{x:Type TextBlock}"> 
             <Setter Property="Background" Value="Red" /> 
            </Style> 
            <Style x:Key="{x:Type cor:String}" TargetType="{x:Type TextBlock}"> 
             <Setter Property="Background" Value="Green" /> 
            </Style> 
            <Style x:Key="{x:Type sys:Uri}" TargetType="{x:Type TextBlock}"> 
             <Setter Property="Background" Value="Blue" /> 
            </Style> 
           </my:TypeSwitchConverter> 
          </Binding.Converter> 
         </Binding> 
        </TextBlock.Style> 
       </TextBlock> 
      </DataTemplate> 
     </ListBox.ItemTemplate> 
    </ListBox> 
+0

Danke für die schnelle Antwort! Das Problem ist nur, dass ich verschiedene Steuerelemente in einem Stapelbereich je nach dem Typ in der Elementauflistung hinzufügen möchte. Wie würdest du das lösen? So wie wenn eine , die je nach Typ in der ItemsCollection sollte verschiedene Steuerelement Objekt hinzugefügt haben. –

+0

Dann binden Sie einfach die 'ItemTemplate' -Eigenschaft mit' TypeSwitchConverter' oben auf andere Vorlagen. –

+0

Eigentlich eine kleine Korrektur - Sie können es nicht direkt binden, weil Sie beim Setzen von ItemTemplate kein aktuelles Objekt haben. Sie definieren also eine 'ItemTemplate', die ein einzelnes Element eines beliebigen Typs (z. B.' ContentPresenter') enthält, und binden dann die 'Template'-Eigenschaft dieses Elements mithilfe eines Switch-Konverters. –

4

Einer WPF-only Lösung:

Ich bin ein wenig zu spät für die Partei, aber wenn jemand anderes versucht, etwas zu tun, Es gibt eine WPF-Lösung. Es gibt keine Datagrid Klasse, die direkt für die richtige Datatemplate aussehen wird, aber wir können indirekt eine Content wie folgt verwenden:

<Window.Resources> 
    <DataTemplate DataType="{x:Type models:Employee}"> 
     <Grid>...</Grid> 
    </DataTemplate> 

    <DataTemplate DataType="{x:Type models:Manager}"> 
     <Grid>...</Grid> 
    </DataTemplate> 
</Window.Resources> 

<DataGrid ... > 
    <DataGrid.Columns> 
     <DataGridTemplateColumn Header="MyColumn"> 
      <DataGridTemplateColumn.CellTemplate> 
       <DataTemplate> 
        <ContentPresenter Content="{Binding}" /> 
       </DataTemplate> 
      </DataGridTemplateColumn.CellTemplate> 
     </DataGridTemplateColumn> 
    </DataGrid.Columns> 
</DataGrid> 

Durch einen Content in einem Datatemplate in der Celltemplate sandwichartig, erreichen wir das gewünschte Ergebnis .

+0

Große Lösung, aber ist es möglich, es auf mehr als eine Spalte zu erweitern? Wie können wir die "richtigen" Datenvorlagen für verschiedene Spalten (z. B. Titel und Unterpositionen) auswählen, wenn wir uns nur auf DataType verlassen? – mechanic