2

我有一个应用程序需要显示主要由布尔值组成的数据网格,并且复选框列符合要求。大约有 40-60 个复选框列,大约 200 行。我认为在 WPF 中做类似的事情是微不足道的。

我什至无法使用 WPF 获得体面的水平滚动体验。要查看我在说什么,请创建 aWindow并在其上放置 a ,然后DataGrid设置AutoGenerateColumns="True",然后在构造函数之后添加以下内容InitializeComponent();

dataGrid1.ItemsSource = Create(200, i => new { b1 = true, b2 = false, b3 = true, b4 = false, b5 = true, b6 = false, b7 = true, b8 = false, b9 = true,
                                               b10 = false, b11 = true, b12 = false, b13 = true, b14 = false, b15 = true, b16 = false, b17 = true, b18 = false, b19 = true, b20 = false, b21 = true,
                                               b22 = false, b23 = true, b24 = false, b25 = true, b26 = false, b27 = true, b28 = false, b29 = true, b30 = false, b31 = true, b32 = false });

它需要这个方法,也添加它:

ObservableCollection<T> Create<T>(int count, Func<int, T> creator)
{
    return new ObservableCollection<T>(Enumerable.Range(0, count).Select(creator));
}

运行应用程序,并尝试水平滚动。可怕,不是吗?垂直滚动也不太热。

我对 WinForms 应用程序做了同样的事情,并且在所有方向上滚动都非常流畅,并且在将DataGridView'DoubleBuffered属性强制为true. 为了比较,创建一个 new Form, plop aDataGridView并将以下内容添加到构造函数 after InitializeComponent();

typeof(DataGridView).GetProperty("DoubleBuffered", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(dataGridView1, true, null);
for (int i = 0; i < 64; i++)
    dataGridView1.Columns.Add(new DataGridViewCheckBoxColumn {HeaderText = "C" + i, Width = 30});
for (int i = 0; i < 400; i++)
    dataGridView1.Rows.Add();

它有两倍的列数,两倍的行数,并且它在水平和垂直方向上都像新生儿的底部一样平滑。

但不幸的是,我不能用 WinForms 做我需要的事情。我需要模板列。我需要可组合性。

为了解决 WPF 中的滚动问题,我尝试了以下所有组合:

  • EnableColumnVirtualization(真/假)
  • EnableRowVirtualization(真/假)
  • ScrollViewer.CanContentScroll (true/false) -false仅改进垂直滚动
  • 固定大小的列
  • 固定大小的数据网格
  • VirtualizingStackPanel.VirtualizationMode (Recycling/Standard) -Recycling有一个错误,它会回收CheckBox选中的控件并将其放置在应该取消选中的新行中,从而导致动画淡出。这使得复选框看起来具有“重影”效果。
  • ScrollViewer.IsDeferredScrollingEnabled - 很抱歉,但我不能接受降级到 Windows 3.1 样式的滚动,因为这太微不足道了。

我愿意接受低于标准的表现。我不期望像 WinForms 的流畅性(WPF 毕竟给了我这么多,尽管这应该被 WPF 的 GPU 加速所抵消)。我只想要一些可用的东西,即使只是勉强可用。

4

2 回答 2

1

这主要是因为 CheckBox 可视化树相当复杂。如果您重新设计视觉树的样式,您可以获得更好的性能。

虽然 ControlTemplate(单边框)中只有单个元素,但没有滞后或延迟。您可以从这里获得特定样式:http: //msdn.microsoft.com/en-us/library/ms752319%28v=vs.85%29.aspx

肯定会花一些时间在数据绑定上。看到这个: 数据绑定优化,它解释了绑定到通常的属性需要更长的时间。通常是因为它涉及反射。使用依赖属性时,不涉及反射。据我所知。

你的班级肯定不大,但你肯定能考上。如果一切都是依赖属性,它会表现得更好吗?

如果您遇到任何问题,请告诉我。

于 2012-09-01T18:53:28.293 回答
1

正如我在评论中所说,我不确定这个问题。如果您正在 WPF 中寻找网格的性能,请转到 ListView / GridView。除非您必须拥有 DataGrid 的某些功能。这是更多的代码,但值得。我有一个 GridView,它有 40 列和 1000 行,性能很好(DataGrid 性能很差)。

于 2012-09-01T19:02:26.180 回答