2

我有一个 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 列,并且我为 dataGrid 启用了虚拟化)。

如果我摆脱样式,响应时间仍然比我想要的要长,但我可以做到。

那么有没有更好的方法来做到这一点?

我也尝试在 Xaml 中使用这种样式,但它似乎不能很好地处理列的虚拟化,即:我将单元格的背景设置为绿色,然后向右滚动整个页面,并且单元格最终与如果我涂成绿色的单元格应该是红色的,它会获得绿色事件:在我将当前行移动到包含该单元格的行之前,该值不会更新......另外,它似乎根本没有提高性能......

谢谢分享

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

  • 具有动态列的数据网格(列的数量和类型仅在运行时知道
  • 在任何时候,我都可以更改单个单元格的任何样式属性:字体(如果应用了系列、大小、样式、粗细、装饰)、前景、背景、textAlignment(如果有)等...

这正是我必须实现的。知道我发现启用列虚拟化后,您无法操作 REAL dataGridCells,因为它们可能尚未显示(虚拟化),然后您失去了属性值的更改。所以我选择了这个“hack”:我将实际 dataGridCell 样式中的每个属性都绑定到“逻辑”属性,然后修改逻辑属性。但这很慢。

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

4

1 回答 1

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>
于 2011-02-01T17:25:01.090 回答