[解決済み] WPFのDataGridを可変のカラム数にバインドするには?
2022-07-27 04:41:06
質問
私のWPFアプリケーションは、毎回異なる数の列を持つ可能性のあるデータのセットを生成します。 出力には、書式設定を適用するために使用される各列の記述が含まれます。 出力の単純化されたバージョンは次のようなものです。
class Data
{
IList<ColumnDescription> ColumnDescriptions { get; set; }
string[][] Rows { get; set; }
}
このクラスはWPFのDataGridのDataContextとして設定されていますが、実際にはプログラムでカラムを作成しています。
for (int i = 0; i < data.ColumnDescriptions.Count; i++)
{
dataGrid.Columns.Add(new DataGridTextColumn
{
Header = data.ColumnDescriptions[i].Name,
Binding = new Binding(string.Format("[{0}]", i))
});
}
このコードをXAMLファイルのデータバインディングに置き換える方法はないでしょうか?
どのように解決するのですか?
DataGridのColumnsをBindするためのワークアラウンドです。ColumnsプロパティはReadOnlyなので、みんなが気づいたように、BindableColumnsというAttached Propertyを作り、CollectionChangedイベントを通してコレクションが変わるたびにDataGridのColumnsを更新しています。
もし、このようなDataGridColumnのコレクションがあるとすれば
public ObservableCollection<DataGridColumn> ColumnCollection
{
get;
private set;
}
そして、BindableColumns を ColumnCollection に以下のようにバインドします。
<DataGrid Name="dataGrid"
local:DataGridColumnsBehavior.BindableColumns="{Binding ColumnCollection}"
AutoGenerateColumns="False"
...>
付属のプロパティ BindableColumns
public class DataGridColumnsBehavior
{
public static readonly DependencyProperty BindableColumnsProperty =
DependencyProperty.RegisterAttached("BindableColumns",
typeof(ObservableCollection<DataGridColumn>),
typeof(DataGridColumnsBehavior),
new UIPropertyMetadata(null, BindableColumnsPropertyChanged));
private static void BindableColumnsPropertyChanged(DependencyObject source, DependencyPropertyChangedEventArgs e)
{
DataGrid dataGrid = source as DataGrid;
ObservableCollection<DataGridColumn> columns = e.NewValue as ObservableCollection<DataGridColumn>;
dataGrid.Columns.Clear();
if (columns == null)
{
return;
}
foreach (DataGridColumn column in columns)
{
dataGrid.Columns.Add(column);
}
columns.CollectionChanged += (sender, e2) =>
{
NotifyCollectionChangedEventArgs ne = e2 as NotifyCollectionChangedEventArgs;
if (ne.Action == NotifyCollectionChangedAction.Reset)
{
dataGrid.Columns.Clear();
foreach (DataGridColumn column in ne.NewItems)
{
dataGrid.Columns.Add(column);
}
}
else if (ne.Action == NotifyCollectionChangedAction.Add)
{
foreach (DataGridColumn column in ne.NewItems)
{
dataGrid.Columns.Add(column);
}
}
else if (ne.Action == NotifyCollectionChangedAction.Move)
{
dataGrid.Columns.Move(ne.OldStartingIndex, ne.NewStartingIndex);
}
else if (ne.Action == NotifyCollectionChangedAction.Remove)
{
foreach (DataGridColumn column in ne.OldItems)
{
dataGrid.Columns.Remove(column);
}
}
else if (ne.Action == NotifyCollectionChangedAction.Replace)
{
dataGrid.Columns[ne.NewStartingIndex] = ne.NewItems[0] as DataGridColumn;
}
};
}
public static void SetBindableColumns(DependencyObject element, ObservableCollection<DataGridColumn> value)
{
element.SetValue(BindableColumnsProperty, value);
}
public static ObservableCollection<DataGridColumn> GetBindableColumns(DependencyObject element)
{
return (ObservableCollection<DataGridColumn>)element.GetValue(BindableColumnsProperty);
}
}
関連
-
[解決済み】"The ConnectionString property has not been initialized "を修正する方法
-
[解決済み】値が期待した範囲に収まらない
-
[解決済み】Unity 「関連するスクリプトを読み込むことができません」「Win32Exception: システムは指定されたファイルを見つけることができません"
-
[解決済み】「...は'型'であり、与えられたコンテキストでは有効ではありません」を解決するにはどうすればよいですか?(C#)
-
[解決済み】値をNULLにすることはできません。パラメータ名:source
-
[解決済み】OnCollisionEnter2Dが実行されない?
-
[解決済み] ...基礎となる接続は閉じられました。予期しないエラーが受信で発生しました
-
[解決済み】 C# 条件演算子エラー 代入、call、increment、decrement、await、new object 式のみ文として使用可能です。
-
[解決済み] 乱数(int)を生成する方法を教えてください。
-
[解決済み] RelativeSourceでWPFバインディングを使用するにはどうしたらいいですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】「未割り当てのローカル変数を使用」とはどういう意味ですか?
-
[解決済み】プログラム実行中に1秒待つ
-
[解決済み] [Entity Framework 4.1でエンティティに関連オブジェクトを追加する際に、エンティティオブジェクトをIEntityChangeTracker.の複数のインスタンスから参照できない。
-
[解決済み] 'SubSonic.Schema .DatabaseColumn' 型のオブジェクトをシリアライズする際に、循環参照が検出されました。
-
[解決済み】「入力文字列が正しい形式ではありませんでした」エラーの解決方法は?[重複しています]。
-
[解決済み】「namespace x already contains a definition for x」エラーの修正方法は?VS2010にコンバートした後に発生しました。
-
[解決済み] 'IEnumerable<SelectListItem>' 型の ViewData アイテムで、キーが国であるものは存在しない。
-
[解決済み】"指定されたパスのフォーマットはサポートされていません。"
-
[解決済み】ファイルやアセンブリ、またはその依存関係の1つをロードできませんでした。
-
[解決済み】ユーザー設定値を別のユーザー設定値で設定する