각 그룹 이름에 대해 Group
클래스의 인스턴스가 하나만 있다고 보장 할 수 없다고 가정합니다. (? 다른 당신이 알려진 그룹 목록을 기반으로 열을 생성하는 것입니다 것은 더) 여기
는
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
방법으로 시작됩니다. 먼저 고유 한 그룹 이름 목록을 가져옵니다. 그룹 이름에 자연스럽게 헤더를 설정하는 각 그룹 이름에 대해 새 텍스트 열을 생성합니다.
열에 바인딩을 설정할 때 이상한 점이 나타납니다. 바인딩에는 변환기가 주어졌으며이 변환기는 SeatsGrid
클래스에서도 구현하기로 결정했습니다. converter 매개 변수는 그룹 이름입니다. 경로가 지정되지 않았기 때문에 바인딩이 실제로 발생할 때 전체 Seats
개체가 변환기로 전달됩니다.
이제 IValueConverter.Convert
방법을 살펴보십시오. converter 매개 변수와 이름이 같은 자리에 Group
의 인스턴스 (있는 것)를 찾습니다. 발견되면 반환 할 값을 검색하기위한 키로 Group
을 사용합니다.
그룹이 이름별로 고유 한 것으로 알려진 경우 코드는 단순화 될 수 있지만 원칙은 동일합니다.
지금까지 우리는 해당 열에 머리글에 열과 셀 값이 있습니다. 얼마나 많은 세포가 그 컬럼을 가질 것으로 기대합니까? 어디에서 행이 나오는가? – AnthonyWJones
우리는 List 항목이이고 여기에 5 개의 항목이 들어 있고, 각각은 "GroupA", "GroupB"및 "GroupC"라는 이름 속성을 가진 3 개의 그룹을 갖습니다. 항목 1 : ID : 1에는 GroupA : 100 GroupB가 : 200 GroupC 300 항목 2 : ID : 2에는 GroupA : 1000 GroupB가 : 2000 GroupC 3000 –
SiN
확인 다음 5 개 항목은 다음과 같이 나누어진다 조금 생각할지도 모르는 질문. 두 개의 서로 다른'Seats' 인스턴스 (각각이'List'의 멤버)는 "GroupA"라는 이름을 가진 그룹에 대한 각각의 'Values' 사전에 엔트리를 가지고 있습니다. 그들은 둘 다'Group'의 단일 인스턴스를 참조합니까 __or__ 그들 각각은'Id'와'Name'에 대해 같은 값을 갖는'Group'의 다른 인스턴스를 가지고 있습니까? –
AnthonyWJones