我有一个 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 样式中的每个属性都绑定到“逻辑”属性,然后修改逻辑属性。但这很慢。
希望我能更好地解释自己。