WPF Datagrid Background abhängig von ausgeblendeter Spalte

Letztens wurde ich von einem ehemaligen Kursteilnehmer gefragt, wie man in WPF die Werte einzelner Zellen abhängig von einer anderen Spalte – welche jedoch ausgeblendet ist – anders einfärbt.

Die Idee:
Die Kunden sollen je nach Typ mit einer anderen Farbe hinterlegt werden. Typ A – Blau Typ B – Grün Typ C – Rot Die Spalte Typ sollte jedoch nicht angezeigt werden.

image

Die Kunden müssen also in einer Auflistung vorliegen. Dazu benötigen wir erstmal eine einfache Model Klasse Kunde.

public class Kunde
{
    public string Typ { get; set; }
    public string Name { get; set; }
}
 

Um das Beispiel einfach zu halten, lasse ich mir die Liste einfach mit ein paar Dummy-Daten in der Code Behind Datei füllen. Dazu habe ich mir eine eigene Methode GetData() geschrieben.

private IEnumerable<Kunde> GetData()
{
    var list = new List<Kunde>();

    list.Add(new Kunde { Typ="A", Name="Kunde1" });
    list.Add(new Kunde { Typ="B", Name="Kunde2" });
    list.Add(new Kunde { Typ="C", Name="Kunde3" });
    list.Add(new Kunde { Typ="B", Name="Kunde4" });
    list.Add(new Kunde { Typ="A", Name="Kunde5" });
    list.Add(new Kunde { Typ="C", Name="Kunde6" });
    list.Add(new Kunde { Typ="C", Name="Kunde7" });
    list.Add(new Kunde { Typ="A", Name="Kunde8" });

    return list;
}

Schauen wir uns die Oberfläche genauer an.
Da die Spalte für den Typ ja nicht angezeigt werden soll, sage ich dem Datagrid AutoGenerateColums=False. Dies bedeutet jedoch, ich muss mich selber um die Spalten kümmern – in meinem Beispiel noch einfach, dies kann jedoch bei größeren Tabellen auch zu einiger Arbeit führen. Ich erstelle also eine Spalte und binde sie auf das Property Name des jeweiligen Listen Items.

<Grid>
   <Grid.Resources>
      <converters:TypToBrushConverter x:Key="typToBrushConverter" />
   </Grid.Resources>
   <DataGrid x:Name="dataGrid" HorizontalAlignment="Left" Margin="44,32,0,0" 
             VerticalAlignment="Top" Height="261" Width="438" 
             AutoGenerateColumns="False">
      <DataGrid.Columns>
         <DataGridTextColumn Binding="{Binding Name}">
            <DataGridTextColumn.CellStyle>
               <Style TargetType="DataGridCell">
                  <Setter Property="Background"
       Value="{Binding Path=Typ, Converter={StaticResource typToBrushConverter}}" />
               </Style>
            </DataGridTextColumn.CellStyle>
         </DataGridTextColumn>
      </DataGrid.Columns>
   </DataGrid>
</Grid>

Die ItemsSource des Datagrids habe ich übrigens im Konstruktor des MainWindows gesetzt.
public MainWindow()
{
    InitializeComponent();

    this.dataGrid.ItemsSource = this.GetData();
}
 

Jetzt fehlt nur mehr der Teil, den Hintergrund der Namenszellen einzufärben. Dies habe ich mit einem Converter realisiert. Ein Converter ist einfach eine Klasse, die das Interface IValueConverter implementiert. Ich habe ihn TypToBrushConverter genannt – da ich einen String in einen SolidColorBrush konvertieren muss.

public object Convert(object value, Type targetType, object parameter, CultureInfo culture) {…}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) {…}

 

Was bringt uns das Interface IValueConverter? Es zwingt uns dazu, zwei Methoden bereit zu stellen.
Die ConvertBack Methode wird in den wenigsten Fällen ausprogrammiert.
Für unser Beispiel wichtig ist die Convert Methode. Wir müssen uns also selber darum kümmern, unseren String in einen SolidColorBrush zu konvertieren. Ich hab das Ganze einfach mit einem switch-case gelöst. Wichtig ist dabei die Typüberprüfung, ob es sich überhaupt um einen string handelt, den wir vom XAML-Teil bereitgestellt bekommen.

public class TypToBrushConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value is string)
            switch ((string)value)
            {
                case "A":
                    return new SolidColorBrush(Colors.Red);
                case "B":
                    return new SolidColorBrush(Colors.LightBlue);
                case "C":
                    return new SolidColorBrush(Colors.Green);
            }
         return null;
    }
    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

So sieht mein „Design-Award-Verdächtiges“ Programm nun aus. Ich hoffe, ich konnte dem einen oder anderen weiterhelfen.

2016-01-13 (1)

Die Projektdatei dazu kann man jederzeit hier herunterladen: ProjektDatei

Kommentare sind geschlossen