WPF настраивает внешний вид ячейки в DataGrid или GridView, используя код позади - PullRequest
0 голосов
/ 13 июля 2011

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

Данные, заполняемые в сетку, в конечном итоге будут представлены в виде плоского файла, который будет проанализирован и собран в DataTable или в какую-либо форму сбора, которую я свяжу с сеткой. Для тестирования я просто привязываю образец DataSet к сетке.

На основании значения в разных ячейках мне нужно изменить внешний вид ячейки, содержащей данные. Например, если какая-либо ячейка в столбце «Приоритет» имеет значение меньше 5, измените фон на красный или если любая ячейка в столбце «Тип» имеет значение «ПОЛЕ», измените фон на зеленый.

Особое условное форматирование будет применяться ко всем ячейкам только в определенном столбце. К конкретному столбцу может быть применено несколько условных форматов.

Мне бы хотелось что-то, что будет работать со стандартными элементами управления DataGrid или GridView, так как они включены в WPF. Я использую Visual Studio 2010.


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

В любых примерах, которые я видел, которые мне не подходят, используются конвертеры с жестко заданными атрибутами условного форматирования. Мне нужно сделать это полностью динамично. Я предпочитаю использовать код позади, если это возможно.

Любая помощь очень ценится.


Обновлено

Я разработал решение моей первоначальной проблемы. Вот что я сделал.

        foreach (ColumnEntity column in ColumnList)
        {
            DataGridTemplateColumn newColumn = CreateDataGridColumn(column, ColumnList.FormatConditionGroups);
            newColumn.Header = column.Header;
            newColumn.Width = new DataGridLength(column.DisplayWidth);
            _dataGrid.Columns.Add(newColumn);
        }

Тогда в CreateDataGridColumn у меня есть.

    private DataGridTemplateColumn CreateDataGridColumn(ColumnEntity dataColumn, FormatConditionGroup formatConditionGroup)
    {
        DataGridTemplateColumn newColumn = new DataGridTemplateColumn();
        DataTemplate dataTemplate = new DataTemplate();

        String triggerValue;

        // Create the label that will display the cell contents
        FrameworkElementFactory labelFNFactory;
        labelFNFactory = new FrameworkElementFactory(typeof(Label));
        Binding binding = new Binding();
        binding.Path = new PropertyPath(dataColumn.Tag);
        labelFNFactory.SetBinding(Label.ContentProperty, binding);
        labelFNFactory.Name = dataColumn.Name;
        labelFNFactory.SetValue(Label.VerticalContentAlignmentProperty, VerticalAlignment.Center);
        labelFNFactory.SetValue(Label.MarginProperty, new Thickness(-2));
        dataTemplate.VisualTree = labelFNFactory;

        if (formatConditionGroup != null)
        {
            foreach (FormatCondition formatCondition in formatConditionGroup.FormatConditionItems)
            {
                // Check to see if this is the target column for the format condition
                if (formatCondition.GetPropertyValue("Target") == dataColumn.Tag)
                {
                    // Create a data trigger to apply the format condition
                    DataTrigger trigger = new DataTrigger();

                    // Set up the binding to the source column, typically this will be the current column but it could be different
                    trigger.Binding = new Binding { Path = new PropertyPath(formatCondition.Source) };
                    trigger.Value = formatCondition.Value;

                    // Check to see if we need to change the text color
                    if ((triggerValue = formatCondition.TextColor) != null)
                        trigger.Setters.Add(new Setter(Label.ForegroundProperty, new SolidColorBrush((Color)ColorConverter.ConvertFromString(triggerValue)), textBlockName));

                    // Check to see if we need to change the background color
                    if ((triggerValue = formatCondition.BackColor) != null)
                        trigger.Setters.Add(new Setter(Label.BackgroundProperty, new SolidColorBrush((Color)ColorConverter.ConvertFromString(triggerValue)), textBlockName));
                    dataTemplate.Triggers.Add(trigger);
                }
            }
        }

        newColumn.CellTemplate = dataTemplate;

        return newColumn;
    }

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

Теперь у меня новая проблема.

Имея в виду, что он должен быть динамичным, как его можно расширить, чтобы принять несколько условий? Например, если «Тип» - «PT» или «Тип -« FT », установите фон в черный цвет, или если« Тип »-« PS », а« Приоритет »-« 10 », установите фон в синий.

В дополнение к этому, как я могу применить условие форматирования ко всей строке?

1 Ответ

2 голосов
/ 13 июля 2011

Я создал образец .... Код XAML ...

 <DataGrid Name="myDataGrid" AutoGenerateColumns="False">
            <DataGrid.Columns>
                <DataGridTemplateColumn Header="Priority" Width="Auto" MinWidth="100" >
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <Grid>
                                <Grid.Style>
                                    <Style>
                                        <Style.Triggers>
                                            <DataTrigger Binding="{Binding Type}" Value="FIELD">
                                                <Setter Property="Grid.Background" Value="Red"/>
                                            </DataTrigger>
                                            <DataTrigger Binding="{Binding Type}" Value="NOT A FIELD">
                                                <Setter Property="Grid.Background" Value="Green"/>
                                            </DataTrigger>
                                        </Style.Triggers>
                                    </Style>
                                </Grid.Style>
                                <TextBlock Text="{Binding Type}"></TextBlock>
                            </Grid>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
                <DataGridTemplateColumn Header="Type" Width="Auto" MinWidth="100" >
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <Grid>
                                <Grid.Style>
                                    <Style>
                                        <Style.Triggers>
                                            <DataTrigger Binding="{Binding Priority}" Value="1">
                                                <Setter Property="Grid.Background" Value="Red"/>
                                            </DataTrigger>
                                            <DataTrigger Binding="{Binding Priority}" Value="2">
                                                <Setter Property="Grid.Background" Value="Green"/>
                                            </DataTrigger>
                                            <DataTrigger Binding="{Binding Priority}" Value="3">
                                                <Setter Property="Grid.Background" Value="Blue"/>
                                            </DataTrigger>
                                            <DataTrigger Binding="{Binding Priority}" Value="4">
                                                <Setter Property="Grid.Background" Value="Yellow"/>
                                            </DataTrigger>
                                            <DataTrigger Binding="{Binding Priority}" Value="0">
                                                <Setter Property="Grid.Background" Value="Orange"/>
                                            </DataTrigger>
                                        </Style.Triggers>
                                    </Style>
                                </Grid.Style>

                                <TextBlock Text="{Binding Priority}">
                                </TextBlock>
                            </Grid>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
            </DataGrid.Columns>
        </DataGrid>

Код позади ...

          List<Temp> items = new List<Temp>();
            Random rand = new Random();
            for (int i = 0; i < 20; i++)
            {
                items.Add(new Temp { Priority = rand.Next(0, 5), Type = i % 2 == 0 ? "FIELD" : "NOT A FIELD" });
            }
            myDataGrid.ItemsSource = items;


 public class Temp
        {
            public string Type { get; set; }
            public int Priority { get; set; }

        }

, выглядит так ......

enter image description here

...