如何动态设置WPF DataGridCell的样式

时间:2011-02-01 15:58:17

标签: wpf datagrid binding styling datagridcell

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

dg.ItemsSource = new ObservableCollection<myRow>

...

public class myRow : Collection<myDataGridCell> { ... }

...

public interface ImyDataGridCell
{
    Brush Background { get; set; }
    Brush Foreground { get; set; }
}

然后我为每种类型的列/单元格都有类:

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的Background属性绑定到我的单元格表示的Background属性,从而随时修改单元格的背景。

现在我的主要问题是这种做事方式会让dataGrid变得像地狱一样慢...... 我为每个单元格绑定了大约15个属性,当我显示100个cols x 20行时,显示dataGrid需要一秒钟以上,然后在水平滚动时大约需要一秒钟刷新它(我的屏幕只能允许20个cols一次,我为dataGrid启用了虚拟化。)

如果我摆脱了样式,响应时间仍然比我想要的还多,但我可以用它做。

那么有更好的方法吗?

我也尝试在Xaml中使用这种风格,但它似乎不能很好地应对列的虚拟化,即:我将单元格的背景设置为绿色,然后向右滚动整页,最后以相同的方式滚动单元格作为我绘制绿色的单元格的位置如果它应该是红色则获得绿色事件:值不会更新,直到我将当前行移动到包含单元格的行... 另外,它似乎根本没有提高性能......

感谢分享,如果你有任何关于此事的/ tip /之前的经验,我愿意尝试一切可能使这个该死的dataGrid加载更快......

编辑:我希望实现的一般效果:

  • 带有动态列的dataGrid(列的数量和类型仅在运行时已知
  • 在任何时候,我都可以更改单个单元格的任何样式属性:字体(系列,大小,样式,重量,装饰如果应用),前景,背景,textAlignment(如果有的话)......

这正是我必须实现的目标。 知道我发现在启用列虚拟化时,你无法操纵REAL dataGridCells,因为它们可能尚未显示(虚拟化),然后你松开了属性值的变化。所以我选择了“hack”:我将实际dataGridCell样式中的每个属性绑定到“逻辑”属性,然后修改逻辑层。但这是懒散的。

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

1 个答案:

答案 0 :(得分:1)

有没有机会看到你缓慢的Xaml?我原本以为用数据触发器做这件事并不会太糟糕(你使用哪个版本的数据网格作为.net 4.0和WPF Toolkit版本是不同的)

我已经做了这样的事情来重新选择所选项目并且它看起来并不太慢(这不是正确的解决方案,但在我再说之前我还想要更多细节):

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