Цикл через WPF DataGrid с помощью foreach

все, я пытаюсь выполнить цикл через WPF DataGrid использование a для каждого цикла для изменения цвета фона ошибочных ячеек. Я проверил много вопросов, но мне еще предстоит найти достаточный ответ. То, что у меня есть до сих пор

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!
            }
        }
    }
}

проблема в том, что для того, чтобы изменить Background цвет строки в моем DataGrid мне нужно работать с DataGridRow объект ascociated с DataRowView rv.

как мне получить ссылку на DataGridRow от объекта rv (DataRowView)?

Спасибо за ваше время.

правка. Основываясь на приведенном ниже совете, у меня теперь есть следующий стиль, который работает с мышью над событием и устанавливает шрифт назад и вперед соответствующей ячейки. Тем не менее, я действительно потерял, как применить backcolor к ячейке во время выполнения в моем коде выше. Стиль XML-это

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

5 ответов


когда вы работаете с WPF, не всегда доступ к артефактам пользовательского интерфейса напрямую.

создайте в ModelView цвет свойства и привяжите его к цвету фона одного шаблона строки вашего представления DataGrid.

поэтому, чтобы изменить цвет, вы будете циклически бросать Коллектон ModelView и устанавливать / читать свойство цвета каждого отдельного объекта, привязанного к каждой отдельной строке. Изменяя его, если привязка правильно settuped, вы будете влиять ряд цвет интерфейса внешний вид.

для конкретного образца вы можете посмотреть дальше:

как привязать фон строки сетки данных к определенному цвету?


можно использовать ItemContainerGenerator чтобы получить визуальное представление данных, т. е. DataGridRow -

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

ответ "Killercam" работал для меня, но мне нужно было добавить:

myDataGrid.UpdateLayout();

перед использованием методов GetCell, поэтому я уверен, что не получаю нулевую ссылку.

чтобы получить весь вспомогательный класс, посмотрите на DataGridHelper

после всей этой боли я пробую весь код, и я столкнулся с другой проблемой, которая заключается в том, что правильно окрашенные ячейки изменились во время прокрутки, решение состояло в том, чтобы включить виртуализацию и установить ее режим Норматив.

VirtualizingStackPanel.IsVirtualizing="True"
VirtualizingStackPanel.VirtualizationMode="Standard"

Итак, надеюсь, это поможет любому, кому нужно будет перебирать ячейки datagrid.


после долгого чтения я нашел способ сделать то, что я хотел - цветные ячейки во время выполнения в зависимости от определенных условий. Это метод, который я использую для окрашивания

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);
            }
        }
    }
}

Это связанные методы утилиты, необходимые

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;
    }
}

обратите внимание, однако, что цвет ячеек перемещается из ячейки в ячейку, когда пользователь прокручивает!? Это еще одно удивительное раздражение WPF. Я действительно смущен, почему что-то такое простое может быть настолько сложным. Этот предложение о том, что нам нужно использовать шаблон типа MVVM для такого рода вещей, я нахожу удивительным...

Я надеюсь, что это поможет кому-то еще.


//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