Поскольку, вы сказали, что все в порядке, чтобы сломать шаблон MVVM, пожалуйста, попробуйте следующий подход.
ОБЗОР:
СоздайтеIvalueConverter для преобразования вашего источника данных в список раскрывающихся объектов
В коде за DataGrid (событие Loaded или SourceChanged) добавьте код для генерации столбцов вручную
КОДЫ:
Создать конвертер: ЧАСТЬ 1 Сначала нам нужно получить список всех возможных столбцов, которые могут появиться (поскольку мы незнать коллекции еще)
ObservableCollection<Person> inputlist = (ObservableCollection<Person>)value;
List<string> PossibleColumnList = new List<string>();
PossibleColumnList.Add(nameof(Person.Name)); //since we need name header first.
List<string> TempColumnList = new List<string>();
foreach (Person P in inputlist)
{
foreach(Treat T in P.Treats)
{
if (TempColumnList.Contains(T.Name) == false) TempColumnList.Add(T.Name);
}
}
TempColumnList.Sort();
PossibleColumnList.AddRange(TempColumnList); //This way we get Name first and rest of the columns in sorted out manner
Создать конвертер: ЧАСТЬ 2 .Теперь создайте объект IDictionary со всеми доступными заголовками столбцов
IDictionary<string, object> ColumnHeaderDictionary = new Dictionary<string, object>();
foreach (string columnheader in PossibleColumnList)
{
if (ColumnHeaderDictionary.ContainsKey(columnheader) == false) ColumnHeaderDictionary.Add(columnheader, new object());
}
Создать конвертер: PART 3 Теперь выполните итерацию по всем лицам и создайте IDictionary для каждой модели людей.Преобразовать идиктивный объект в расширенный формат и сохранить в окончательном списке
List<ExpandoObject> FinalList = new List<ExpandoObject>();
foreach (Person p in inputlist)
{
ExpandoObject tempExpando = new ExpandoObject();
IDictionary<string, object> TempDictionary = tempExpando as IDictionary<string, object>;
foreach (var kvp in ColumnHeaderDictionary)
{
TempDictionary.Add(kvp);
}
TempDictionary[nameof(Person.Name)] = p.Name;
foreach(Treat t in p.Treats)
{
TempDictionary[t.Name] = t.Value;
}
FinalList.Add(tempExpando);
}
return FinalList;
КОД XAML:
<Window.DataContext>
<local:ViewModel/>
</Window.DataContext>
<Grid x:Name="grdMain" DataContext="{Binding}">
<DataGrid x:Name="dgMain" ItemsSource="{Binding ElementName=grdMain,Path=DataContext.Model.Persons,Converter={StaticResource NewConverter}}" Loaded="dgMain_Loaded" />
</Grid>
КОД ЗА СОБОЙ: ВРУЧНУЮ СОЗДАТЬ КОЛОННЫ
private void dgMain_Loaded(object sender, RoutedEventArgs e)
{
DataGrid workinggrid = sender as DataGrid;
ExpandoObject SingleExpando = (workinggrid.ItemsSource as List<ExpandoObject>).FirstOrDefault();
if (workinggrid == null) workinggrid = new DataGrid();
List<string> ColumHeaders = (SingleExpando as IDictionary<string, object>).ToList().Select(p => p.Key).ToList();
foreach (string ColumnName in ColumHeaders)
{
var newcolumn = new DataGridTextColumn() { Header = ColumnName, Binding = new Binding(ColumnName) };
workinggrid.Columns.Add(newcolumn);
}
}
ЗАКЛЮЧИТЕЛЬНЫЙ ВЫХОД: