定義: WPF .NET 4.0 グリッド コントロールのデータ ソースとして機能する文字列の 2D 配列 (約 10 列、1,600 行、固定長 7 文字) を使用して、次のコード スニペットを使用してグリッドにデータを入力します。配列からの値を表示するラベル。注: Grid は XAML に追加され、PopulateGrid 関数に渡されました (リスト 1 を参照)。視覚的な出力は、基本的に読み取り専用モードの表形式のデータ表現です (双方向バインディングは必要ありません)。
問題: パフォーマンスが重要な問題です。強力な Intel-i3/8GB-DDR3 PC で実行されているこの操作を完了するのに、気が遠くなるような 3...5 秒かかりました。したがって、この WPF グリッドのパフォーマンスは、通常の WinForm データ対応コントロールや Excel ワークシートなどの同様のコントロール/タスクとの比較に基づいて、予想よりも少なくとも 1 桁遅くなります。
質問 1 :上記のシナリオでWPF グリッドのパフォーマンスを向上させる方法がある場合は? 以下のリスト 1 とリスト 2 に示すコード スニペットに対する回答/改善の可能性を教えてください。
質問 1aDataGrid
: 提案されたソリューションは、追加のデータベース対応コントロールへのデータ バインディングを実装できますDataTable
。リスト 2 でコンバーターを追加string[,]
したので、追加のコントロール(またはその他の) のプロパティを にバインドできます。したがって、最も単純な形式で、オブジェクトへの WPF のデータ バインディングに関するコンパクトな (望ましくは、古いスタイルのデータ認識コントロールで行われたように、数行のコードについて) 効率的な (パフォーマンス面での) ソリューションを提供していただけますか?DataTable dt
DataContext
ItemsSource
dt.DefaultView
DataGrid
DataTable
どうもありがとう。
リスト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。の場合のように、Content の代わりに Text プロパティを使用してLabel
コントロールを置き換えることをお勧めします。これにより、実行が少し高速化されます。また、コード スニペットは VS 2012 for Win 8 と前方互換性があり、.TextBlock
Label
Label
注 3 : これまでのところ (リスト 3 の XAML を参照) へのバインドDataGrid
を試みましDataTable
たが、パフォーマンスは非常に貧弱です (grdOut
はネストGrid
された であり、表形式のデータのコンテナーとして使用されました。 _dataGrid
は のデータ認識オブジェクト型ですDataGrid
)。
リスト 3 . DataGrid
binding to DataTable
: パフォーマンスが悪かったので、それを削除しましたが、正常にScrollViewer
動作していません。
<ScrollViewer ScrollViewer.CanContentScroll="True" VerticalScrollBarVisibility="Auto" >
<Grid Name="grdOut">
<DataGrid AutoGenerateColumns="True" Name="_dataGrid" ItemsSource="{Binding Path=.}" />
</Grid>
</ScrollViewer>