Laden...

DataGrid Zeilen anhand Wert in einer Zelle ändern

Erstellt von sgnirdrol vor 10 Jahren Letzter Beitrag vor 10 Jahren 7.031 Views
S
sgnirdrol Themenstarter:in
16 Beiträge seit 2013
vor 10 Jahren
DataGrid Zeilen anhand Wert in einer Zelle ändern

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


Two Damn Geeks - 2dmg.org - Andorim

Andorim's Blog - blog.andorim.de - Andorim

R
212 Beiträge seit 2012
vor 10 Jahren

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

P
660 Beiträge seit 2008
vor 10 Jahren

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"

S
sgnirdrol Themenstarter:in
16 Beiträge seit 2013
vor 10 Jahren

@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.


Two Damn Geeks - 2dmg.org - Andorim

Andorim's Blog - blog.andorim.de - Andorim

P
660 Beiträge seit 2008
vor 10 Jahren

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"

R
212 Beiträge seit 2012
vor 10 Jahren

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.

S
sgnirdrol Themenstarter:in
16 Beiträge seit 2013
vor 10 Jahren

Okay, Danke euch beiden. Werde es versuchen so umzusetzen.


Two Damn Geeks - 2dmg.org - Andorim

Andorim's Blog - blog.andorim.de - Andorim

S
sgnirdrol Themenstarter:in
16 Beiträge seit 2013
vor 10 Jahren

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.


Two Damn Geeks - 2dmg.org - Andorim

Andorim's Blog - blog.andorim.de - Andorim

P
660 Beiträge seit 2008
vor 10 Jahren

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"