Hallo zusammen,
ich hoffe ich finde nach langem suchen und rumprobieren eine Lösung für mein Problem.
Ich versuche in einem DataGrid, die Zeilen Hintergründe anhand eines Wertes in einer Zelle zu ändern.
Ich benutze momentan diesen Code:
foreach (DataRow item in dataGrid1.Items)
{
DataGridRow row = dataGrid1.ItemContainerGenerator.ContainerFromIndex(i) as DataGridRow;
try
{
if (row == null)
{
//dataGrid1.UpdateLayout();
dataGrid1.ScrollIntoView(dataGrid1.Items[i]);
row = dataGrid1.ItemContainerGenerator.ContainerFromIndex(i) as DataGridRow;
}
if (item.ist == item.soll)
{
row.Background = new SolidColorBrush(Color.FromRgb(0x63, 0x9c, 0x18));
}
else if (item.ist < item.soll && item.ist != 0)
{
enabled = false;
row.Background = Brushes.Orange;
}
else
{
enabled = false;
row.Background = Brushes.Red;
}
}
catch (NullReferenceException ex)
{
Console.Write(ex.StackTrace);
enabled = false;
}
i++;
}
Das Ganze sieht in der GUI wie auf dem Bild datagrid.png im Anhang aus.
Wenn der wert in der Spalte "Soll" = dem Wert in "Ist" ist soll die Zeile Grün sein.
Wenn ist != 0 aber kleiner als Soll ist, soll die Zeile Orange sein.
Sonst sollen die Zeilen Rot sein.
Solange ich kein Scrollbalken habe funktioniert alles einwandfrei. Sobals aber man aber scrollt verschieben sich die einfärbung.
Ich hoffe Ihr könnt mir Helfen
Grüße
Verwende doch eine zählerschleife wenn du schon "i" verwendest, und dann
if(DataGridViev["ist",i] == DaDataGridViev["soll",i])
DataGridViev.Rows_Background = Color.Orange;
.
.
.
Edit: Funktioniert nur bei DataGridViev´s
Wieso machst du das hier
DataGridRow row = dataGrid1.ItemContainerGenerator.ContainerFromIndex(i) as DataGridRow;
statt
item.BackgroundColor = Brushes.Orange;
MfG
ProGamer*Der Sinn Des Lebens Ist Es, Den Sinn Des Lebens Zu Finden!
*"Wenn Unrecht zu Recht wird dann wird Widerstand zur Pflicht."
*"Ignorance simplifies ANY problem."
*"Stoppt die Piraterie der Musikindustrie"
@Robin0
Weil es keine DataGridView ist sondern ein DataGrid. Das DataGrid hat keine Eigenschaft "Rows".
@ProGamer
item ist vom Typ DataRow, welchen ich selbst definiert habe. Eine Liste von DataRows ist, die ItemSource des DataGrids. Um die DataGridRows aus dem DataGrid zu bekommen, benutze ich den ItemContainerGenerator.
Die nächste frage:
wieso definierst du das selbst? es reicht aus dem DataContext des DataGrids eine List<YourClass> zu
übergeben.
du kannst auf XAML ebene mit Style.Triggers und DataTrigger arbeiten. Müsstest dann nur selbst
einen Converter schreiben, der dir den vergleich liefert (-1 kleiner, 0 gleichgroß, und 1 größer ist
so das gängigste was du auch im Inet finden wirst).
Werte vergleichen, und dann entsprechend den Background setzen.
MfG
ProGamer*Der Sinn Des Lebens Ist Es, Den Sinn Des Lebens Zu Finden!
*"Wenn Unrecht zu Recht wird dann wird Widerstand zur Pflicht."
*"Ignorance simplifies ANY problem."
*"Stoppt die Piraterie der Musikindustrie"
Ja ok stimmt 😄 hab ich überlesen.
Also, du adressierst den Container in deinem Datagrid, da sich deine Items einen Container nach oben verschieben wenn du runter scrollst passt die Farbaufteilung nichtmehr;
Entweder du berechnest den farbwert immer wider manuell neu.
Oder ich denke mal du verwendest XML, mach ein Databinding auf die Container indem du einen converter verwendest der dies für dich berechnet.
Also ich habe es jetzt mit einem Style- und Data-Trigger, wie von euch vorgeschlagen realisiert und es klappt wunderbar. Danke dafür.
Hab es zwar noch eine Status Spalte in das DataGrid hinzugefügt um es einfacher Binden zu können.
IM XAML sieht es so aus:
<DataGrid.RowStyle>
<Style TargetType="{x:Type DataGridRow}">
<Style.Triggers>
<DataTrigger Binding="{Binding Status}" Value="X">
<Setter Property="Background" Value="Red"></Setter>
</DataTrigger>
<DataTrigger Binding="{Binding Status}" Value="O">
<Setter Property="Background" Value="Orange"></Setter>
</DataTrigger>
<DataTrigger Binding="{Binding Status}" Value="Y">
<Setter Property="Background" Value="#639c18"></Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</DataGrid.RowStyle>
Und der dazugehörige Code, welcher den Status setzt so:
try
{
if (row.soll == row.ist)
{
row.Status = "Y";
}
else if ((row.soll > row.ist) && (row.ist != 0))
{
row.Status = "O";
}
else
{
row.Status = "X";
}
dataGrid1.Items.Refresh();
dataGrid1.UpdateLayout();
//dataGrid1.SelectedItem = dataGrid1.Items[index];
dataGrid1.CurrentCell = new DataGridCellInfo(dataGrid1.Items[index], dataGrid1.Columns.First());
dataGrid1.Focus();
dataGrid1.ScrollIntoView(dataGrid1.CurrentCell.Item);
}
catch (Exception ex)
{
Console.Write(ex.StackTrace);
}
Momentan bin ich grade noch am Überlegen wie ich eine bestimmte Zelle selektiere um damit die zu letzt veränderte Zeile zu makieren.
eigentlich müsste es ausreichen wenn du den Status setzt und dann das NotifyPropertyChanged-Event feuerst. Das Binding hast du ja schon.
MfG
ProGamer*Der Sinn Des Lebens Ist Es, Den Sinn Des Lebens Zu Finden!
*"Wenn Unrecht zu Recht wird dann wird Widerstand zur Pflicht."
*"Ignorance simplifies ANY problem."
*"Stoppt die Piraterie der Musikindustrie"