私は、グループ名ごとにGroup
クラスが1つしか存在しないことを保証することはできません。 (そうでないあなたがいない既知のグループのリストに基づいて列を生成するのでしょうか?)
ここDataGrid
から派生したクラスです。
public class SeatsGrid : DataGrid, IValueConverter
{
public SeatsGrid()
{
AutoGenerateColumns = false;
}
#region public List<Seats> SeatsList
public List<Seats> SeatsList
{
get { return GetValue(SeatsListProperty) as List<Seats>; }
set { SetValue(SeatsListProperty, value); }
}
public static readonly DependencyProperty SeatsListProperty =
DependencyProperty.Register(
"SeatsList",
typeof(List<Seats>),
typeof(SeatsGrid),
new PropertyMetadata(null, OnSeatsListPropertyChanged));
private static void OnSeatsListPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
SeatsGrid source = d as SeatsGrid;
List<Seats> value = e.NewValue as List<Seats>;
source.OnSeatsListPropertyChanged(value);
}
private void OnSeatsListPropertyChanged(List<Seats> value)
{
ItemsSource = null;
Columns.Clear();
var groups = value
.SelectMany(seats => seats.Values.Keys)
.Select(g => g.Name)
.Distinct();
foreach (var group in groups)
{
DataGridTextColumn col = new DataGridTextColumn();
col.Binding = new Binding()
{
Converter = this,
ConverterParameter = group
};
col.Header = group;
Columns.Add(col);
}
ItemsSource = value;
}
#endregion public List<Seats> SeatsList
object IValueConverter.Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
Seats seats = (Seats)value;
string group = (string)parameter;
Group actualGroup = seats.Values.Keys.FirstOrDefault(g => g.Name == group);
if (actualGroup != null)
{
return seats.Values[actualGroup].ToString();
}
else
{
return null;
}
}
object IValueConverter.ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
XAMLに入れ、このクラスのインスタンスを、そのにList<Seats>
を割り当てますSeatsList
プロパティを使用し、列を生成して行をレンダリングします。
どのように動作しますか?
魔法はOnSeatsListPropertyChanged
メソッドで開始します。最初に異なるグループ名のリストを取得します。グループ名ごとに新しいText列を生成し、グループ名に自然にヘッダを設定します。
列のバインディングを設定すると、奇妙なことが表示されます。バインディングには変換器が与えられており、私はSeatsGrid
クラスに実装することを決定しました。 converterパラメータはグループ名です。パスが指定されていないので、バインディングが実際に発生すると、Seats
オブジェクト全体がコンバーターに渡されます。
IValueConverter.Convert
の方法を見てください。コンバータパラメータと同じ名前を持つ座席に、Group
というインスタンスが存在することがわかります。見つかった場合は、返す値を検索するためのキーとしてGroup
を使用します。
グループが名前ごとに一意であることが分かっていた場合、コードは簡略化できますが、原則は同じです。
これまでのところ、その列には列とセルの値のヘッダーがあります。列に何個の他のセルがあると思いますか?どこから行が出るのですか? – AnthonyWJones
Listに5つの項目が含まれているとします。それぞれには、「GroupA」、「GroupB」、および「GroupC」というnameプロパティを持つ3つのグループがあります。 アイテム1:ID:1、グループA:100、グループB:200、GroupC:300 アイテム2 ID:2、グループA:1000、グループB:2000、GroupC:3000 –
SiN
OK次 5つの項目は以下のように分割され少し考えてみるかもしれない質問。 'Seats'の2つの異なるインスタンス(それぞれ、' List 'のメンバー)は、どちらも、名前が「GroupA」であるグループのそれぞれの「Values」辞書にエントリを持っています。彼らはどちらも 'Group'の単一のインスタンスを参照していますか__or__それぞれは' Id'と 'Name'に対して同じ値を持つ' Group'の異なるインスタンスを持っていますか? –
AnthonyWJones