Reputation: 501
I'm currently struggling with DataGridComboBoxColumn in C# WPF.
I have the class ToolModel
class ToolModel
{
public long Id { get; set; }
public string Number { get; set; }
public string Name { get; set; }
public string Coating { get; set; }
public bool Thread { get; set; }
public string Kind { get; set; }
public ToolTypeModel Type { get; set; }
}
and the class ToolTypeModel
public class ToolTypeModel
{
public long Id { get; set; }
public string Name { get; set; }
}
The data is stored into a database and loaded into my ViewModel
class ToolsViewModel
{
public ObservableCollection<ToolModel> Tools { get; set; }
public ObservableCollection<ToolTypeModel> ToolTypes { get; set; }
public ToolsViewModel()
{
Tools = new ObservableCollection<ToolModel>(ToolModel.GetTools());
ToolTypes = new ObservableCollection<ToolTypeModel>(ToolTypeModel.GetToolTypes());
}
}
I want to display the data in a DataGrid and attempted to add a DataGridComboBoxColumn to select a ToolType for the corresponding Tool. Therefore I added following xaml definition (which is already a workaround - but the only way I was able to get it nearly working):
<DataGrid x:Name="ToolsDataGrid" ItemsSource="{Binding Tools}" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Header="Nummer" Binding="{Binding Number}" />
<DataGridComboBoxColumn
Header="Typ"
SelectedValueBinding="{Binding Type, Mode=TwoWay}"
SelectedValuePath="Id"
DisplayMemberPath="Name">
<DataGridComboBoxColumn.ElementStyle>
<Style TargetType="{x:Type ComboBox}">
<Setter Property="ItemsSource" Value="{Binding Path=DataContext.ToolTypes, RelativeSource={RelativeSource AncestorType={x:Type Window}}}" />
</Style>
</DataGridComboBoxColumn.ElementStyle>
<DataGridComboBoxColumn.EditingElementStyle>
<Style TargetType="{x:Type ComboBox}">
<Setter Property="ItemsSource" Value="{Binding Path=DataContext.ToolTypes, RelativeSource={RelativeSource AncestorType={x:Type Window}}}" />
</Style>
</DataGridComboBoxColumn.EditingElementStyle>
</DataGridComboBoxColumn>
</DataGrid.Columns>
</DataGrid>
It shows all elements of ToolTypes but not the selected one my Tool has a reference on.
Any ideas how I can look up the ToolTypes into the ComboBoxColumn and show the referenced Type as selected item?
Thanks in advance.
Upvotes: 3
Views: 4119
Reputation: 37066
SelectedValuePath
is the path to a property of the combobox items that will be bound via the SelectedValueBinding
. Therefore, SelectedValueBinding
must bind to a property of the same type.
<DataGridComboBoxColumn
Header="Typ"
SelectedValueBinding="{Binding Type, Mode=TwoWay}"
SelectedValuePath="Id"
DisplayMemberPath="Name">
If you had a ToolTypeId
property, you'd use SelectedValuePath
to bind to that:
class ToolModel
{
public long Id { get; set; }
public string Number { get; set; }
public string Name { get; set; }
public string Coating { get; set; }
public bool Thread { get; set; }
public string Kind { get; set; }
// Like so
public long ToolTypeId { get; set; }
public ToolTypeModel Type { get; set; }
}
And in the XAML:
<DataGridComboBoxColumn
Header="Typ"
SelectedValueBinding="{Binding ToolTypeId}"
SelectedValuePath="Id"
DisplayMemberPath="Name">
But I don't think that's what you want. I think it's pretty clear you want to get an actual ToolTypeModel
instance in your Type
property.
So this should work (I just tested it). Take car, however: Overriding Equals()
is a little sketchy because it changes the semantics of the C# =
and !=
operators for that class, which can bite you.
public class ToolTypeModel
{
public long Id { get; set; }
public string Name { get; set; }
public override bool Equals(object obj)
{
return (obj is ToolTypeModel)
? (obj as ToolTypeModel).Id == Id
: false;
}
public override int GetHashCode()
{
return Id.GetHashCode();
}
}
XAML:
<DataGridComboBoxColumn
Header="Type"
SelectedItemBinding="{Binding Type}"
DisplayMemberPath="Name"
>
(Also, get rid of Mode=TwoWay
-- that's the default for bindings on that property, you'll get it anyway).
Upvotes: 5