定义:将二维字符串数组(大约 10 列,1,600 行,固定长度的 7 个字符)用作 WPF .NET 4.0 Grid 控件的数据源,使用以下代码片段来填充 Grid标签显示数组中的值。注意:Grid 已添加到 XAML 并传递给函数 PopulateGrid(参见清单 1)。视觉输出本质上是只读模式下的表格数据表示(不需要双向绑定)。
问题:性能是一个关键问题。在功能强大的 Intel-i3/8GB-DDR3 PC 上运行此操作需要令人难以置信的 3...5 秒;因此,恕我直言,此 WPF Grid 性能至少比预期慢一个数量级,基于与类似控件/任务的比较,例如常规 WinForm 数据感知控件,甚至 Excel 工作表。
问题1:是否有办法在上述场景中提高WPF Grid的性能?请将您的答案/可能的改进指向下面清单 1 和清单 2 中提供的代码片段。
问题 1aDataGrid
:建议的解决方案可以将数据绑定到额外的数据感知控件,例如DataTable
. 我在清单 2 中添加string[,]
了DataTable dt
转换器,以便可以将附加控件的DataContext
(或ItemsSource
其他)属性绑定到dt.DefaultView
. 那么,以最简单的形式,您能否提供一个紧凑的(最好是几行代码,因为它是在旧式数据感知控件中完成的)和高效(性能方面)的 WPF 数据绑定DataGrid
到DataTable
object的解决方案?
非常感谢。
清单 1。Grid GridOut
从 2D填充 WPF 的过程string[,] Values
#region Populate grid with 2D-array values
/// <summary>
/// Populate grid with 2D-array values
/// </summary>
/// <param name="Values">string[,]</param>
/// <param name="GridOut">Grid</param>
private void PopulateGrid(string[,] Values, Grid GridOut)
{
try
{
#region clear grid, then add ColumnDefinitions/RowsDefinitions
GridOut.Children.Clear();
GridOut.ColumnDefinitions.Clear();
GridOut.RowDefinitions.Clear();
// get column num
int _columns = Values.GetUpperBound(1) + 1;
// add ColumnDefinitions
for (int i = 0; i < _columns; i++)
{
GridOut.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
}
// get rows num
int _rows = Values.GetUpperBound(0) + 1;
// add RowDefinitions
for (int i = 0; i < _rows; i++)
{
GridOut.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) });
}
#endregion
#region populate grid w/labels
// populate grid w/labels
for (int i = 0; i < _rows; i++)
{
for (int j = 0; j < _columns; j++)
{
// new Label control
Label _lblValue = new Label();
// assign value to Label
_lblValue.Content = Values[i, j].ToString();
// add Label to GRid
GridOut.Children.Add(_lblValue);
Grid.SetRow(_lblValue, i);
Grid.SetColumn(_lblValue, j);
}
}
#endregion
}
catch
{
GridOut.Children.Clear();
GridOut.ColumnDefinitions.Clear();
GridOut.RowDefinitions.Clear();
}
}
#endregion
清单 2。转换string[,]
_DataTable
#region internal: Convert string[,] to DataTable
/// <summary>
/// Convert string[,] to DataTable
/// </summary>
/// <param name="arrString">string[,]</param>
/// <returns>DataTable</returns>
internal static DataTable Array2DataTable(string[,] arrString)
{
DataTable _dt = new DataTable();
try
{
// get column num
int _columns = arrString.GetUpperBound(1) + 1;
// get rows num
int _rows = arrString.GetUpperBound(0) + 1;
// add columns to DataTable
for (int i = 0; i < _columns; i++)
{
_dt.Columns.Add(i.ToString(), typeof(string));
}
// add rows to DataTable
for (int i = 0; i < _rows; i++)
{
DataRow _dr = _dt.NewRow();
for (int j = 0; j < _columns; j++)
{
_dr[j] = arrString[i,j];
}
_dt.Rows.Add(_dr);
}
return _dt;
}
catch { throw; }
}
#endregion
注 2。建议使用其 Text 属性而不是 Content替换Label
控件,例如. 它将稍微加快执行速度,而且代码片段将与 VS 2012 for Win 8 向前兼容,其中不包含.TextBlock
Label
Label
注意 3:到目前为止,我已经尝试绑定DataGrid
到DataTable
(参见清单 3 中的 XAML),但性能很差(grdOut
是一个嵌套Grid
的,用作表格数据的容器;_dataGrid
是一种数据感知对象类型DataGrid
)。
清单 3。DataGrid
绑定到DataTable
:性能很差,所以我删除了它ScrollViewer
,但它运行不正常。
<ScrollViewer ScrollViewer.CanContentScroll="True" VerticalScrollBarVisibility="Auto" >
<Grid Name="grdOut">
<DataGrid AutoGenerateColumns="True" Name="_dataGrid" ItemsSource="{Binding Path=.}" />
</Grid>
</ScrollViewer>