将带有样式的多个DataGridCell以编程方式添加到wpf dgv中的一行

时间:2016-12-24 23:26:32

标签: c# wpf datagridview colors

我有一个班级Ro,有4个字段(2个名字和2个颜色)

public class Ro
    {
        public string c1 { get; set; }
        public SolidColorBrush c1Color { get; set; }
        public string c2 { get; set; }
        public SolidColorBrush c2Color { get; set; }
    }

我创建了List of Ro objects

List<Ro> data = new List<Ro>();
            data.Add(new Ro()
            {
                c1 = "7B",
                c1Color = Brushes.Green,
                c2 = "",
                c2Color = Brushes.White
            });
            data.Add(new Ro()
            {
                c1 = "Jot",
                c1Color = Brushes.Green,
                c2 = "",
                c2Color = Brushes.Black
            });
            data.Add(new Ro()
            {
                c1 = "Nav",
                c1Color = Brushes.White,
                c2 = "",
                c2Color = Brushes.Orange
            });

现在我想使用这个List填充wpf DataGridView在循环列表时根据对象的当前字段为每个单元格分配颜色

为此,我创建了一个为每个单元格创建ControlTemplate的方法:

        public ControlTemplate CellTemplate(string text, SolidColorBrush color)
        {
            ControlTemplate template = new ControlTemplate();
            template.VisualTree = new FrameworkElementFactory(typeof(TextBlock));
            template.VisualTree.SetValue(TextBlock.TextProperty, text);
            template.VisualTree.SetValue(TextBlock.BackgroundProperty, color);
            template.VisualTree.SetValue(TextBlock.TextAlignmentProperty, TextAlignment.Center);
            template.VisualTree.SetValue(TextBlock.FontWeightProperty, FontWeights.Bold);
            if (color == Brushes.White)
                template.VisualTree.SetValue(TextBlock.ForegroundProperty, Brushes.Black);
            else
                template.VisualTree.SetValue(TextBlock.ForegroundProperty, Brushes.White);
            return template;
        }

我还创建了一个dataColumn c1

dataGrid1.Columns.Add(
    new DataGridTextColumn
    { Header = "c1" });

最后在foreach循环中我创建了带样式的单元格

foreach (Ro me in data)
{
    DataGridCell cell0 = new DataGridCell { Template = CellTemplate(me.c1,me.c1Color) };
    dataGrid1.Items.Add(cell0);
  }

enter image description here

到目前为止一直很好,但是当我添加第二列并尝试应用相同的想法,如

 dataGrid1.Columns.Add(
    new DataGridTextColumn
    { Header = "c2" });

foreach (Ro me in data)
{
    DataGridCell cell0 = new DataGridCell { Template =    CellTemplate(me.c1,me.c1Color) };
    dataGrid1.Items.Add(cell0);

   DataGridCell cell1 = new DataGridCell { Template = CellTemplate(me.c2, me.c2Color) };
    dataGrid1.Items.Add(cell1);
}

我得到例外:

  

未处理System.ArgumentOutOfRangeException   System.Windows.Media.VisualCollection.get_Item(Int32 index)          在System.Windows.Controls.UIElementCollection.get_Item(Int32索引)上          在System.Windows.Controls.UIElementCollection.System.Collections.IList.get_Item(Int32)上   指数)          在System.Windows.Controls.DataGridCellsPanel.ArrangeOverride(Size   arrangeSize)...

如果我在dgv中只有一列我得到: enter image description here

我尝试过以下操作但出错了,我不知道如何在dgv中的特定列中插入特定的单元格...

 foreach (Ro me in data)
            {
                DataGridCell cell0 = new DataGridCell { Template = CellTemplate(me.c1, me.c1Color) };
                DataGridCell cell1 = new DataGridCell { Template = CellTemplate(me.c2, me.c2Color) };
                dataGrid1.Columns.Insert(0, cell0);
                dataGrid1.Columns.Insert(1, cell0);
                //dataGrid1.Items.Add(cell0);
                //dataGrid1.Items.Add(cell1);
            }

如何以编程方式连续添加单元格?

1 个答案:

答案 0 :(得分:1)

如果不做一些体操,这是不可能的。像这样添加你的列:

this.dataGrid.Columns.Add(
    new DataGridTextColumn
    { Header = "c1", Binding = new Binding("c1") } );

this.dataGrid.Columns.Add(
    new DataGridTextColumn
    { Header = "c2", Binding = new Binding("c2") });
this.dataGrid.LoadingRow += DataGrid_LoadingRow;

foreach (Ro me in data)
{
    dataGrid.Items.Add(me);
}

查看代码如何将C1列绑定到c1的{​​{1}}属性。了解代码如何订阅Ro事件。以下是异步调用LoadingRow方法的行的处理程序:

AlterRow

这是代码的其余部分,它基本上在每列的第0列和第1列中找到单元格,然后计算出背景属性并设置它。

private void DataGrid_LoadingRow(object sender, DataGridRowEventArgs e)
{
    Dispatcher.BeginInvoke(DispatcherPriority.Render, new Action(() => AlterRow(e)));
}

部分代码是从here借来的。