Laden...

Farben innerhalb einer DataGridComboBoxColumn

Erstellt von Jan68 vor 2 Jahren Letzter Beitrag vor 2 Jahren 189 Views
J
Jan68 Themenstarter:in
2 Beiträge seit 2021
vor 2 Jahren
Farben innerhalb einer DataGridComboBoxColumn

Hallo Forengemeinde,
ich bin noch nicht so tief in der Programmierung und versuche schon seit einiger Zeit mit folgendem Problem umzugehen:
Angenommen ich habe zwei (fiktive) Klassen


    public class Genre
    {
        public int ID { get; set; }
        public string Bezeichnung { get; set; }
        public string Farbe { get; set; }

        public Genre(int id, string bezeichnung, string farbe)
        {
            this.ID = id;
            this.Bezeichnung = bezeichnung;
            this.Farbe = farbe;
        }
    }

    public class Band
    {
        public int ID { get; set; }
        public string Bezeichnung { get; set; }
        public int GenreID { get; set; }
        public Genre Genre { get; set; }

        public Band(int id, string bezeichnung, int genreID)
        {
            this.ID = id;
            this.Bezeichnung = bezeichnung;
            this.GenreID = genreID;
        }
    }

und initialisiere diese mit


    public partial class MainWindow : Window
    {
        public ObservableCollection<Genre> Genres { get; set; }
        public ObservableCollection<Band> Bands { get; set; }

        public MainWindow()
        {
            InitializeComponent();
            
            Genres = new ObservableCollection<Genre>();
            Genres.Add(new Genre(1, "Heavy Metal", "#999999"));
            Genres.Add(new Genre(2, "Hard Rock", "#99EEEE"));
            Genres.Add(new Genre(3, "Rock", "#6699EE"));
            Genres.Add(new Genre(4, "Blues", "#AAAAFF"));

            Bands = new ObservableCollection<Band>();
            Bands.Add(new Band(1, "Iron Maiden", 1));
            Bands.Add(new Band(2, "Judas Priest", 1));
            Bands.Add(new Band(3, "Accept", 1));
            Bands.Add(new Band(4, "Deep Purple", 2));
            Bands.Add(new Band(5, "Rainbow", 2));
            Bands.Add(new Band(6, "Foreigner", 3));
            Bands.Add(new Band(7, "B.B. King", 4));

            foreach (var band in Bands)
            {
                band.Genre = Genres.FirstOrDefault(x => x.ID == band.GenreID);
            }

            this.DataContext = this;
        }
    }

bekomme ich mit diesem XAML


<DataGrid ItemsSource="{Binding Bands}"
              AutoGenerateColumns="False"
              IsReadOnly="True">
        <DataGrid.Columns>
            <DataGridTextColumn Header="ID" Binding="{Binding ID}"></DataGridTextColumn>
            <DataGridTextColumn Header="Band" Binding="{Binding Bezeichnung}"></DataGridTextColumn>
            <DataGridTextColumn Header="Genre" Binding="{Binding Genre.Bezeichnung}">
                <DataGridTextColumn.CellStyle>
                    <Style TargetType="{x:Type DataGridCell}">
                        <Setter Property="Background" Value="{Binding Genre.Farbe}"></Setter>
                    </Style>
                </DataGridTextColumn.CellStyle>
            </DataGridTextColumn>
        </DataGrid.Columns>
    </DataGrid>

folgende farbige Spalten -> FarbigeListe.JPG

So möchte ich die Ausgabe auch haben, mit der DataGridTextColumn funktioniert das Setzten der Hintergrundfarbe auch sehr gut. Was mir nicht gefällt, ist das Property Genre in der Klasse Band, da ich gefühlsmäßig nur die ID zuweisen würde.


public class Band
{
    public int ID { get; set; }
    public string Bezeichnung { get; set; }
    //public Genre Genre { get; set; }
    public int GenreID { get; set; }

   public Band(int id, string bezeichnung, int genreID)
   {
        this.ID = id;
        this.Bezeichnung = bezeichnung;
        this.GenreID = genreID;
    }
}

.
.
.
    Bands.Add(new Band(5, "Rainbow", 2));
    Bands.Add(new Band(6, "Foreigner", 3));
    Bands.Add(new Band(7, "B.B. King", 4));

    //foreach (var band in Bands)
    //{
    //    band.Genre = Genres.FirstOrDefault(x => x.ID == band.GenreID);
    //}

    this.DataContext = this;


und mit dem XAML


<Window.Resources>
    <CollectionViewSource x:Key="Genres" Source="{Binding Genres}" />
</Window.Resources>
<DataGrid ItemsSource="{Binding Bands}" AutoGenerateColumns="False"
          IsReadOnly="True">
    <DataGrid.Columns>
        <DataGridTextColumn Header="ID" Binding="{Binding ID}"></DataGridTextColumn>
        <DataGridTextColumn Header="Band" Binding="{Binding Bezeichnung}"></DataGridTextColumn>
        <DataGridComboBoxColumn Header="Genre"
                ItemsSource="{Binding Source={StaticResource Genres}}"
                SelectedValuePath="ID" SelectedValueBinding="{Binding GenreID}" DisplayMemberPath="Bezeichnung">
            <DataGridComboBoxColumn.CellStyle>
                <Style TargetType="DataGridCell">
                    <Setter Property="Background" Value="{Binding Farbe}"/>
                </Style>
            </DataGridComboBoxColumn.CellStyle>
        </DataGridComboBoxColumn>
    </DataGrid.Columns>
</DataGrid>

bekomme ich jedoch nur eine Spalte ohne Farben -> ListeOhneFarben.JPG
Offensichtlich weiß ich nicht wie ich auf die Collection Genres zugreifen kann


<Style TargetType="DataGridCell">
    <Setter Property="Background" Value="{Binding Farbe}"/>    <!-- Wie komme ich auf den richtigen Wert aus der Collection Genres? -->
</Style>

Damit stellen sich mir mindestens 3 Fragen:
Was ist die bessere Vorgehensweise, im ViewModel (bei einer Umsetzung in MVVM) ein neues erweitertes Model hinzufügen, in dem die Genres als Objekte an den Bands hängen oder einfach nur über die GenreID das passende Genre auswählen?
Wie komme ich in dem DataGrid in der Spalte mit der GenreID auf Bezeichnung und Farbe?
Brauche ich in einem ReadOnly-DataGrid eine DataGridComboBoxColumn oder kann ich auch einer DataGridTextColumn den von der ID abhängigen Wert aus einer Collection zuweisen?

Ich hoffe es ist einigermaßen verständlich ausgedrückt und es kann jemand meine Fragen beantworten.

Vielen Dank
Jan

4.942 Beiträge seit 2008
vor 2 Jahren

Hallo und willkommen,

wenn ich dich richtig verstehe, sollte dir dabei ein IValueConverter helfen, s.a. Gewusst wie: Konvertieren von gebundenen Daten.

In der Convert-Methode suchst du dann die übergebene ID (du bindest also an GenreID) aus der Genre-Liste und gibst dann die passende Farbe zurück (bzw. genauer ein Brush, da Background von diesem Typ ist - per XAML wird das intern automatisch umgewandelt).

Edit: Das sollte dann auch bei einer DataGridTextBoxColumn funktionieren.

Noch ein Edit: Vllt. hilft dir dazu auch WPF Datagrid Background abhängig von ausgeblendeter Spalte (ich hatte diesen Link schon mal irgendwo hier im Forum gepostet).

J
Jan68 Themenstarter:in
2 Beiträge seit 2021
vor 2 Jahren

Danke TH69 für die Antwort.
An einen Converter habe ich gar nicht gedacht. Ich probiere das mal aus. Ich muß nur rausfinden wie ich dem Converter dann die Collection Genres zum Vergleich übergeben kann.
VG
Jan