I have a list of Roles
that I want to have selectable in a DataGrid
cell ComboBox
.
I have the ObservableCollection
Roles
for the ComboBox
being populated in the ViewModel.
For some reason, nothing shows up in the ComboBox
though. What's the proper way of attaching this collection of objects?
Any comments or suggestions would be helpful.
PersonModel:
public int SelectedRole { get; set; }
RoleModel:
public int Id { get; set; }
public int Role { get; set; }
public string Description { get; set; }
public string RoleInfo
{
get
{
return $"{Role} - {Description}";
}
}
ViewModel:
private ObservableCollection<PersonModel> _people;
public ObservableCollection<PersonModel> People
{
get { return _people; }
set
{
_people = value;
NotifyOfPropertyChange(() => People);
}
}
public ObservableCollection<RoleModel> _roles;
public ObservableCollection<RoleModel> Roles
{
get
{
return _roles;
}
set
{
_roles = value;
NotifyOfPropertyChange(() => Roles);
}
}
public PersonViewModel(IEventAggregator events, IWindowManager windowmanager)
{
_events = events;
_windowManager = windowmanager;
sql = "SELECT * FROM People";
People = SqliteConnector.LoadData<PersonModel>(sql, new Dictionary<string, object>());
sql = "SELECT * FROM Roles";
Roles = SqliteConnector.LoadData<PersonModel>(sql, new Dictionary<string, object>());
}
View:
<DataGrid ItemsSource="{Binding Path=People}"
AutoGenerateColumns="False"
CanUserDeleteRows="True"
CanUserReorderColumns="True"
CanUserAddRows="True"
AlternatingRowBackground="#dfdfdf"
cm:Message.Attach="[Event RowEditEnding] = [Action SaveOrUpdate()]">
<DataGridTemplateColumn Header="Type">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=Role}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<ComboBox DisplayMemberPath="RoleInfo"
ItemsSource="{Binding Path=Roles}"
SelectedValue="{Binding Path=SelectedRole, UpdateSourceTrigger=PropertyChanged}"
SelectedValuePath="Role" />
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
</DataGrid>
The DataContext of the "row" elements of the DataGrid is the corresponding item of the ItemsSource collection, i.e. a PersonModel instance - which does of course not have a Roles
property. You should have observed a corresponding data binding error message in the Output Window in Visual Studio.
In order to bind to the Roles property of the parent view model, use an expression like this:
ItemsSource="{Binding DataContext.Roles,
RelativeSource={RelativeSource AncestorType=DataGrid}}"
The SelectedValue Binding could simply be like shown below, because PropertyChanged
is already the default UpdateSourceTrigger
for that property.
SelectedValue="{Binding Path=SelectedRole}"