I am building an MVVM app with AvaloniaUI/ReactiveUI and EF Core to be able to edit a few tables with data. I guess the fact that I use AvaloniaUI does not play too much of a role though. If I had used WPF the problem would probably be the same (seems more to be a ReactiveUI issue).
As an example assume two tables, Classes and Instructors, where Classes holds a foreign key to the Instructors table.
Classes and Instructors have the following models:
class Class
{
//Primary key
public int ID { get; set; }
public string Name { get; set; }
//Foreign key to Instructors table
public int InstructorID { get; set; }
//Navigation property
public Instructor Instructor { get; set; }
}
class Instructor
{
//Primary key
public int ID { get; set; }
public string Name { get; set; }
}
The main view model contains collections both of these as
public List<Class> Classes { get; set; }
public List<Instructor> Instructors { get; set; }
I want the classes to be displayed in a DataGrid. For that I used programmatic (type-safe) ReactiveUI bindings like so
<DataGrid Name="DGClasses">
<DataGrid.Columns>
<DataGridTextColumn Header="Name"
Binding="{Binding Name}" />
<DataGridTextColumn Header="Instructor"
Binding="{Binding Instructor.Name}"/>
</DataGrid.Columns>
</DataGrid>
...
this.OneWayBind(ViewModel, x => x.Classes, x => x.DGClasses.Items);
this.Bind(ViewModel, x => x.SelectedClass, x => x.DGClasses.SelectedItem);
...
So far this works well, the Instructor column even displays the name of the instructor although the Classes table contains only the foreign key into the Instructors table (this works by means of the navigation property in the Class class).
For editing the Instructor of a class the column should use a ComboBox as editor so I can select from all existing Instructors. I started with
<DataGridTemplateColumn Header="Instructor">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox Items="{Binding ??? }">
</ComboBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
But this is where I'm stuck. A direct binding expression does not work because the Instructors collection is not a subproperty of Class and I know of no way to programmatically bind the Items property (ItemsSource in WPF) in a DataTemplate in a DataGrid column. Since I use the programmatic ReactiveUI binding with all (top-level) elements I also don't have set the DataContext property of the Window that contains the DataGrid.
Any idea how to accomplish this?
You can bind your combobox item collection to some special attached property on the DataGrid
(or just use Tag
) and do something like {Binding $parent[DataGrid].Tag}
.