WPF DataGrid: CellStyle-Binding mittels MVVM möglich?

  • WPF

Es gibt 2 Antworten in diesem Thema. Der letzte Beitrag () ist von MarioD.

    WPF DataGrid: CellStyle-Binding mittels MVVM möglich?

    Hallo,

    ich versuche in einem DataGrid den Zellen-Hintergrund in Abhängigkeit ihres Wertes zu setzten (z.B. Wert < 0 = Rot, Wert >0 grün).

    Das ganze möchte ich über MVVM lösen, d.h. ich definiere dem ViewModell eine Variable _style vom Type System.Windows.Style. Dieser wird im Konstruktor automatisch auf Basis
    des Zellenwerts ein Style zugeordnet. Soweit, so gut.

    Nun möchte ich, dass während das Grid mit Daten gefüllt wird, der Cell-Style anhand der _style-Variable gesetzt wird. Das möchte durch eine Bindung der entsprechenden Spalte an der Variable oder einer Methode realisieren.

    C#-Quellcode

    1. //Sorry ... programmiere leider in C#
    2. public void createGrid() {
    3. // ...
    4. var column4 = new DataGridTextColumn();
    5. column4.Header = "Resturlaub";
    6. column4.Binding = new Binding("RestHolidays");
    7. column4.Width = 40;
    8. column4.CellStyle = ***; // <-- Hier hätte ich gerne eine Bindung zu der Variable _style oder einer Methode, die den Wert setzt, z.B. getStyle()
    9. column4.IsReadOnly = true;
    10. dataGrid.Columns.Add(column4);
    11. // ...
    12. dataGrid.ItemsSource = Data.gridPlans;
    13. }
    14. public Style getStyle() {
    15. if (_restUrlaub < 0)
    16. return (Style)FindResource("DataGridCell_RED");
    17. else
    18. return (Style)FindResource("DataGridCell_GREEN");
    19. }


    Ist das auf diese Art und Weise zu realisieren? Wenn ja, wie binde ich die Variable/Methode an den CellStyle-Parameter? Oder habt ihr einen anderen Tip oder Vorschlag für mich?

    Gruß,

    Mario
    Hier ein simples Beispiel (eventuell gibt es andere/bessere Lösungen) wie es mit MVVM möglich wäre:
    XAML:
    Spoiler anzeigen

    XML-Quellcode

    1. <Window x:Class="WpfApplication1.MainWindow"
    2. xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    3. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    4. xmlns:local="clr-namespace:WpfApplication1"
    5. Title="MainWindow" Height="350" Width="525">
    6. <Window.DataContext>
    7. <local:MainViewModel x:Name="vm" />
    8. </Window.DataContext>
    9. <Window.Resources>
    10. <local:IntToBrushConverter x:Key="IntToBrushConverter" />
    11. </Window.Resources>
    12. <DataGrid ItemsSource="{Binding Persons}" AutoGenerateColumns="False">
    13. <DataGrid.Columns>
    14. <DataGridTextColumn Header="Vorname" Binding="{Binding Name}" Width="100"/>
    15. <DataGridTextColumn Header="Nachname" Binding="{Binding Lastname}" Width="100"/>
    16. <DataGridTemplateColumn Header="Alter" Width="50">
    17. <DataGridTemplateColumn.CellTemplate>
    18. <DataTemplate>
    19. <TextBlock Text="{Binding Age}" Background="{Binding Age, Converter={StaticResource IntToBrushConverter}}"/>
    20. </DataTemplate>
    21. </DataGridTemplateColumn.CellTemplate>
    22. </DataGridTemplateColumn>
    23. </DataGrid.Columns>
    24. </DataGrid>
    25. </Window>


    Converter:
    Spoiler anzeigen

    C#-Quellcode

    1. using System;
    2. using System.Collections.Generic;
    3. using System.Linq;
    4. using System.Text;
    5. using System.Threading.Tasks;
    6. using System.Windows.Data;
    7. using System.Windows.Media;
    8. namespace WpfApplication1
    9. {
    10. public class IntToBrushConverter : IValueConverter
    11. {
    12. public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    13. {
    14. int v = (int)value;
    15. if(v > 20)
    16. return new SolidColorBrush(Colors.LightGreen);
    17. else
    18. return new SolidColorBrush(Colors.LightCyan);
    19. }
    20. public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    21. {
    22. return Binding.DoNothing;
    23. }
    24. }
    25. }


    Person Klasse:
    Spoiler anzeigen

    C#-Quellcode

    1. using System;
    2. using System.Collections.Generic;
    3. using System.Linq;
    4. using System.Text;
    5. using System.Threading.Tasks;
    6. namespace WpfApplication1
    7. {
    8. public class Person
    9. {
    10. public string Name { get; set; }
    11. public string Lastname { get; set; }
    12. public int Age { get; set; }
    13. }
    14. }


    MainViewModel:
    Spoiler anzeigen

    C#-Quellcode

    1. using System;
    2. using System.Collections.Generic;
    3. using System.Collections.ObjectModel;
    4. using System.ComponentModel;
    5. using System.Linq;
    6. using System.Runtime.CompilerServices;
    7. using System.Text;
    8. using System.Threading.Tasks;
    9. namespace WpfApplication1
    10. {
    11. public class MainViewModel : INotifyPropertyChanged
    12. {
    13. private ObservableCollection<Person> persons;
    14. public ObservableCollection<Person> Persons
    15. {
    16. get { return persons; }
    17. set
    18. {
    19. persons = value;
    20. OnPropertyChanged();
    21. }
    22. }
    23. public MainViewModel()
    24. {
    25. persons = new ObservableCollection<Person>();
    26. persons.Add(new Person { Name = "Hans", Lastname = "Hanses", Age = 15 });
    27. persons.Add(new Person { Name = "Franz", Lastname = "Mayer", Age = 18 });
    28. persons.Add(new Person { Name = "Petra", Lastname = "Huber", Age = 35 });
    29. }
    30. public event PropertyChangedEventHandler PropertyChanged;
    31. protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
    32. {
    33. var handler = PropertyChanged;
    34. if(handler != null)
    35. handler(this, new PropertyChangedEventArgs(propertyName));
    36. }
    37. }
    38. }


    lg
    ScheduleLib 0.0.1.0
    Kleine Lib zum Anlaufen von Code zu bestimmten Zeiten
    Hallo fichz,

    perfekt! Vielen Dank für deine Hilfe.

    Da ich die Spalten im C#- und nicht im XAML-Code erzeuge, habe ich ein DataTemplate in den Windows Ressourcen angelegt,

    XML-Quellcode

    1. <Window.Resources>
    2. <classes:IntToBrushConverter x:Key="IntToBrushConverter" />
    3. <DataTemplate x:Key="restHolidayTemplate">
    4. <TextBlock Text="{Binding RestHolidays}" Background="{Binding RestHolidays, Converter={StaticResource IntToBrushConverter}}"/>
    5. </DataTemplate>
    6. </Window.Resources>


    mit dessen Hilfe ich bequem im C#-Code die Spalte erzeugen kann,

    C#-Quellcode

    1. DataGridTemplateColumn templateColumn = new DataGridTemplateColumn();
    2. templateColumn.Header = "Resturlaub";
    3. templateColumn.CellTemplate = (DataTemplate)Resources["restHolidayTemplate"];
    4. dataGrid.Columns.Add(templateColumn);


    und meine Felder, gemäß dem Converter, einfärbt.

    Nochmals vielen Dank!

    Gruß,

    Mario