2013-03-27 6 views
6

Alles, ich versuche, eine WPF DataGrid Schleife mit einem a für jede Schleife, um die Hintergrundfarbe von fehlerhaften Zellen zu ändern. Ich habe viele Fragen geprüft, aber ich muss noch eine ausreichende Antwort finden. Was ich bisher habe, istLooping durch WPF DataGrid Verwenden von Foreach

public void RunChecks() 
{ 
    const int baseColumnCount = 3; 
    foreach (DataRowView rv in dataGrid.Items) 
    { 
     for (int i = baseColumnCount; i < dataGrid.Columns.Count; i++) 
     { 
      if (!CheckForBalancedParentheses(rv.Row[i].ToString())) 
      { 
       Color color = (Color)ColorConverter.ConvertFromString("#FF0000"); 
       row.Background = new SolidColorBrush(color); // Problem! 
      } 
     } 
    } 
} 

Das Problem ist, dass, um die Background Farbe einer Zeile in meinem DataGrid ich mit dem DataGridRow Objekt mit den DataRowViewrv ascociated arbeiten muß geändert werden.

Wie bekomme ich einen Verweis auf die DataGridRow vom Objekt rv (DataRowView)?

Danke für Ihre Zeit.

Bearbeiten. Auf der Grundlage des folgenden Hinweises habe ich nun den folgenden Stil, der mit dem Mouse-Over-Ereignis arbeitet und die Vorder- und Rückseite der betreffenden Zelle festlegt. Allerdings bin ich wirklich verloren, wie man die Backcolor auf eine Zelle zur Laufzeit in meinem Code oben anwendet. Die XML-Stil ist

<Window.Resources> 
    <Style TargetType="{x:Type DataGridRow}"> 
     <Style.Triggers> 
      <Trigger Property="IsMouseOver" 
        Value="True"> 
       <Setter Property="Background" Value="Red" /> 
       <Setter Property="FontWeight" Value="ExtraBold" /> 
      </Trigger> 
     </Style.Triggers> 
    </Style> 
</Window.Resources> 

Antwort

5

Wenn Sie mit WPF arbeiten, vermeiden immer Zugriff auf UI-Artefakte direkt.

Erstellen Sie in Ihnen ModelView eine Eigenschaft Color, und binden Sie es an die Hintergrundfarbe einer einzelnen Zeile Vorlage Ihrer DataGrid-Ansicht.

Also, um die Farbe zu ändern, werden Sie die ModelView collecton loop werfen und Color-Eigenschaft von jedem einzelnen Objekt in jeder einzelnen Zeile gebunden/lesen. Wenn die Bindung geändert wird, wirkt sich dies auf die Farbdarstellung der Zeilen-Benutzeroberfläche aus.

Für Betonprobe können Sie sich auf:

How do I bind the background of a data grid row to specific color?

+0

Vielen Dank für Ihre Zeit. Ich werde deinen Rat annehmen und anfangen zu lesen. Ich habe auch versucht, Farbe und ganze Spalte, wieder ohne Glück. Ich habe eine andere Frage gestellt [http://stackoverflow.com/questions/15644105/change-the-background-color-of-entire-column-of-wpf-datagrid-at-runtime], wenn Sie mit dem Geld verbunden werden können und will die rep. Nochmals vielen Dank ... – MoonKnight

+0

@Killercam: Die Idee ist die gleiche für Zeilen und Spalten. Wenn das UI-Objekt eine Eigenschaft (in diesem Fall eine Farbe) enthält, die entweder durch direkten Zugriff oder durch Bindung geändert werden kann, verwenden Sie die Bindung von Ihrem Modelview-Objekt. – Tigran

+0

Danke. Nachdem ich ein Kapitel über ein Buch über Stile, Auslöser usw. gelesen habe, habe ich jetzt die Farbe der Reihe bei einem Mausüber-Ereignis geändert. Ich bin jedoch verloren, wie man eine Zelle/Zeile in der erforderlichen Farbe aus dem Code zur Laufzeit unter Verwendung dieses Stils ändert. Wenn Sie hier Hilfe anbieten können, wäre es sehr hilfreich ... Ich habe die Frage bearbeitet, um den Stil zu zeigen, den ich habe. – MoonKnight

2

Sie die ItemContainerGenerator können Sie die visuelle Darstellung bekommen für Ihre Daten, dh DataGridRow -

DataGridRow row = (DataGridRow)dataGrid.ItemContainerGenerator 
             .ContainerFromItem(rv); 
+0

Dies gibt 'null' für die 'Zeile' zurück. Ich habe check 'rv' und das ist nicht null. Entschuldigen Sie die Störung, danke für Ihre Zeit ... – MoonKnight

+0

Dies wird nur dann 'null' zurückgeben, wenn die Zeile noch nicht auf Ihrer GUI gerendert wurde. Mit wie vielen Zeilen hast du es zu tun, und ist Virtualisierung auf deinem Raster aktiviert? –

+0

Link hier - http://stackoverflow.com/questions/6713365/itemcontainergenerator-containerfromitem-returns-null könnte Ihnen helfen. –

0

Nach viel Lesen ich gefunden habe, ein Weg, um zu tun, was ich wollte - Zellen zur Laufzeit abhängig von bestimmten Bedingungen. Dies ist die Methode, die ich verwenden, um die Färbung erforderlich

public void RunChecks() 
{ 
    const int baseColumnCount = 3; 
    for (int i = baseColumnCount; i < dataGrid.Columns.Count; i++) 
    { 
     foreach (DataGridRow row in Utilities.GetDataGridRows(dataGrid)) 
     { 
      if (row != null) 
      { 
       DataGridCell cell = dataGrid.GetCell(row, i); 

       // Start work with cell. 
       Color color; 
       TextBlock tb = cell.Content as TextBlock; 
       string cellValue = tb.Text; 
       if (!CheckForBalancedParentheses(cellValue)) 
        color = (Color)ColorConverter.ConvertFromString("#FF0000"); 
       else 
        color = (Color)ColorConverter.ConvertFromString("#FFFFFF"); 
       row.Background = new SolidColorBrush(color); 
       //cell.Background = new SolidColorBrush(color); 
      } 
     } 
    } 
} 

Diese sind die zugehörigen Hilfsmethoden

jedoch
public static T GetVisualChild<T>(Visual parent) where T : Visual 
{ 
    T child = default(T); 
    int numVisuals = VisualTreeHelper.GetChildrenCount(parent); 
    for (int i = 0; i < numVisuals; i++) 
    { 
     Visual v = (Visual)VisualTreeHelper.GetChild(parent, i); 
     child = v as T; 
     if (child == null) 
      child = GetVisualChild<T>(v); 
     if (child != null) 
      break; 
    } 
    return child; 
} 

public static DataGridCell GetCell(this DataGrid grid, DataGridRow row, int column) 
{ 
    if (row != null) 
    { 
     DataGridCellsPresenter presenter = GetVisualChild<DataGridCellsPresenter>(row); 
     if (presenter == null) 
     { 
      grid.ScrollIntoView(row, grid.Columns[column]); 
      presenter = GetVisualChild<DataGridCellsPresenter>(row); 
     } 
     DataGridCell cell = (DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(column); 
     return cell; 
    } 
    return null; 
} 

public static IEnumerable<DataGridRow> GetDataGridRows(DataGrid grid) 
{ 
    var itemsSource = grid.ItemsSource as IEnumerable; 
    if (null == itemsSource) yield return null; 
    foreach (var item in itemsSource) 
    { 
     var row = grid.ItemContainerGenerator.ContainerFromItem(item) as DataGridRow; 
     if (null != row) yield return row; 
    } 
} 

Hinweis zu tun, dass die Farbe der Zellen von Zelle zu Zelle bewegen, wenn der Benutzer einen Bildlauf! ? Dies ist noch ein weiterer erstaunlicher Ärger von WPF. Ich bin wirklich verwirrt darüber, warum so etwas so einfach gemacht werden kann. Der Vorschlag, dass wir ein MVVM-Muster für diese Art von Sache verwenden müssen finde ich erstaunlich ...

Ich hoffe, dass dies jemand anderem hilft.

1

die Antwort von „Killercam“ für mich gearbeitet, aber ich hinzufügen musste:

myDataGrid.UpdateLayout();

bevor die GetCell Methoden verwenden, damit ich ich bin sicher, dass ich nicht eine Null-Referenz zu bekommen.

den ganzen Helper Klasse Blick auf DataGridHelper

nach all dem Schmerz zu bekommen, ich den ganzen Code versuchen, und ich stand vor einer weiteren probem weicht ist, dass die richtig gefärbten Zellen während einer Rolle verändert, war die Lösung Virtualisierung zu ermöglichen, und setze seinen Modus auf Standard.

also, hoffe, dass dies jemand helfen wird, die durch Datagrid-Zellen durchlaufen müssen.

0
//the Class that resembles the Datagrid Item schema 

foreach (Class cl in dgDatagrid.Items) 
    { 
     MessageBox.Show(cl.ID.ToString()); 
    } 

this is the most simplest way to read the datagrid data 
most articles misguide such simple things 
+0

Dies gibt keine Antwort auf die Frage. Sobald Sie genug [Reputation] (https://stackoverflow.com/help/whats-reputation) haben, können Sie [jeden Beitrag kommentieren] (https://stackoverflow.com/help/privileges/comment); Stattdessen [geben Sie Antworten, die keine Klärung durch den Fragesteller erfordern] (https://meta.stackexchange.com/questions/214173/why-doe-i-need-50-reputation-to-comment-what-can- i-do-stattdessen). - [Aus Bewertung] (/ review/low-quality-posts/17321773) –