如何动态设置WPF DataGridCell的样式

如何动态设置WPF DataGridCell的样式,wpf,datagrid,binding,styling,datagridcell,Wpf,Datagrid,Binding,Styling,Datagridcell,我有一个DataGrid,其itemsSource定义如下: dg.ItemsSource = new ObservableCollection<myRow> 然后我为每种类型的列/单元格设置了类: public class myTextBoxColumn : DataGridTextColumn {...} public class myTextBoxCell : TextBox, ImyDataGridCell {...} 然后我将每列的CellStyle设置为: 在每列的构

我有一个DataGrid,其itemsSource定义如下:

dg.ItemsSource = new ObservableCollection<myRow>
然后我为每种类型的列/单元格设置了类:

public class myTextBoxColumn : DataGridTextColumn {...}
public class myTextBoxCell : TextBox, ImyDataGridCell {...}
然后我将每列的CellStyle设置为:

在每列的构造函数中:

string source = String.Format(CultureInfo.InvariantCulture, "[{0}].", dataGrid.Columns.Count);
// I set the "source" string to the column's index in the dataGrid's Columns list between [] to get an index in my binding below.

CellStyle = new Style(typeof(DataGridCell));
CellStyle.Setters.Add(new Setter(DataGridCell.BackgroundProperty, new Binding(source + "Background")));
这允许我将实际DataGridCell的背景属性绑定到我的单元格表示的背景属性,从而可以随时轻松地修改单元格的背景

现在我的主要问题是,这种方式会让数据网格变得非常慢。。。 我为每个单元格绑定了大约15个属性,当我显示100列x20行时,显示dataGrid需要一秒钟以上的时间,当我水平滚动时,刷新dataGrid需要一秒钟左右(我的屏幕一次只能允许20列,我为dataGrid启用了虚拟化)

如果我去掉了样式,响应时间仍然比我想要的要长,但我可以用它

那么,有没有更好的方法

我也尝试在Xaml中使用这种风格,但它似乎无法很好地适应专栏的虚拟化,即:我会将单元格背景设置为绿色,然后向右滚动整个页面,最后与我画成绿色的单元格位于相同位置的单元格,如果它应该是红色,则会得到绿色事件:在我将当前行移动到包含该单元格的行之前,该值不会更新。。。 另外,它似乎根本没有改善性能

谢谢分享,如果你有任何关于这件事的想法/提示/经验,我愿意尝试一切可以让这个该死的数据网格加载更快的方法

编辑:我想要达到的一般效果:

  • 具有动态列的数据网格(列的数量和类型仅在运行时已知)
  • 在任何时候,我都可以更改单个单元格的任何样式属性:字体(族、大小、样式、重量、装饰(如果应用))、前景、背景、文本对齐(如果有)等等
这正是我必须做到的。 知道吗,我发现启用列虚拟化后,您无法操作真正的dataGridCell,因为它们可能还没有显示(虚拟化),然后您就失去了属性值的更改。因此我选择了这个“黑客”:我将实际dataGridCell样式中的每个属性绑定到“逻辑”一个,我修改了逻辑的,但这是sloow


希望我能更好地解释我自己。

有没有可能看到您缓慢的Xaml?我会认为使用datatrigger这样做不会太糟糕(另外,您使用的是哪个版本的数据网格作为.net 4.0和WPF Toolkit版本是不同的)

我已经做过类似的事情来重新收集选定的项目,但速度似乎并不太慢(这不是正确的解决方案,但在我说更多之前,我想了解更多细节):



事实上,我想问的是你想要的最终效果是什么?如果你对15个属性这样做对性能来说不是很好。数据模板和触发器可能会更好。@Peterl:谢谢你的反馈,我编辑了我的问题并提供了更多细节,希望这能帮助你解决我的问题。使用tri在我的例子中,ggers是毫无意义的,因为视觉属性与任何东西都没有关联。我只需要能够随时说:“嘿,这个细胞在灰色中看起来很悲伤,让我们给它一个粉色背景吧!”。所以我只需要能够更改背景颜色……我想我可以看到你在用它做什么(我希望你没有这样做)。你能拥有一套“风格”而不是单独的颜色吗?我想我需要在这里放一个样本,感觉我们需要a)有一套风格(“快乐”、“悲伤”、“愤怒”等),然后应用到每个单元格(你能逃脱吗?)b)使用SetValue调用做一些有趣的事情,或者c)找到一些方法使属性绑定动态化。Hmmm需要构建一个小的测试应用程序。(忘记了评论框上的5分钟)@Peterl:你仍然可以删除第一条评论(鼠标经过时在右边划叉)。另外,忘了样式集吧,这当然太容易了;)。。。我需要能够在任何时候应用任何样式,而不事先知道它们,更糟糕的是,每个属性独立于其他属性(即:cometimes只更改背景,有时仅更改前景,有时两者都更改,这有15个属性组合)。。。所以我把头发拔下来。。。
public class myTextBoxColumn : DataGridTextColumn {...}
public class myTextBoxCell : TextBox, ImyDataGridCell {...}
string source = String.Format(CultureInfo.InvariantCulture, "[{0}].", dataGrid.Columns.Count);
// I set the "source" string to the column's index in the dataGrid's Columns list between [] to get an index in my binding below.

CellStyle = new Style(typeof(DataGridCell));
CellStyle.Setters.Add(new Setter(DataGridCell.BackgroundProperty, new Binding(source + "Background")));
        <Style TargetType="DataGrid">
        <Setter Property="CellStyle">
            <Setter.Value>
                <Style TargetType="DataGridCell">
                    <Style.Triggers>
                        <Trigger Property="IsSelected" Value="True">
                            <Setter Property="Background" Value="{StaticResource SelectedBackgroundBrush}" />
                            <Setter Property="BorderBrush" Value="{x:Null}" />
                            <Setter Property="Foreground" Value="White" />
                        </Trigger>
                    </Style.Triggers>
                </Style>
            </Setter.Value>
        </Setter>
    </Style>