I have a Template Column in my DataGrid that looks like this:
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Item}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<ComboBox
DisplayMemberPath="Item"
Header="Item"
ItemsSource="{Binding Data.AssetDescriptions, Source={StaticResource proxy}}"
SelectedValueBinding="{Binding AssetDescriptionID}"
SelectedValuePath="AssetDescriptionID" />
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
The ViewModel has a public property containing the Asset Descriptions:
public IEnumerable<AssetDescription> AssetDescriptions { get; set; }
Where AssetDescription
is essentially:
public class AssetDescription
{
public int AssetDescriptionID { get; set; }
public string Item { get; set; } // Description
}
The DataGrid itself is bound to an ObservableCollection<Asset> Assets
property, where Asset
contains both AssetDescriptionID
and Item
(description). To accomplish that, I join the Assets table to the AssetDescriptions table, like so:
var assets = _conn.Query<Asset>(
@"SELECT A.AssetDescriptionID, D.Item
FROM Assets A
JOIN AssetDescriptions D
ON D.AssetDescriptionID = A.AssetDescriptionID");
Assets = new ObservableCollection<Asset>(assets);
This all works perfectly, except that the TextBlock
in the CellTemplate
DataTemplate
does not get updated to the new description when a new value is selected in the ComboBox
.
How do I accomplish that?
The problem is that you only bind to the AssetDescriptionID
-Property of your Asset
.
Item
will never be touched (which your CellTemplate
binds to).
Option 1:
Try using a DataGridComboBoxColumn
instead of DataGridTemplateColumn
Item
(on Asset
) is then no longer needed
<DataGridComboBoxColumn
DisplayMemberPath="Item"
Header="Item"
ItemsSource="{Binding Data.AssetDescriptions, Source={StaticResource proxy}}"
SelectedValueBinding="{Binding AssetDescriptionID}"
SelectedValuePath="AssetDescriptionID">
</DataGridComboBoxColumn>
Option 2: If you really need the Item
/description on your Asset
Easiest solution will be to bind the whole object(AssetDescription
).
Change your Asset
to this
class Asset
{
...
public AssetDescription AssetDescription {get;set;}
...
}
And your CellEditingTemplate
to this
<DataTemplate>
<ComboBox
DisplayMemberPath="Item"
ItemsSource="{Binding Data.AssetDescriptions, Source={StaticResource proxy}}"
SelectedItem="{Binding AssetDescription }" />
</DataTemplate>
And CellTemplate
to this
<TextBlock Text="{Binding AssetDescription.Item}" />
Edit:
You can also use a DataGridComboBoxColumn
for Option 2
<DataGridComboBoxColumn
DisplayMemberPath="Item"
Header="Item"
ItemsSource="{Binding Data.AssetDescriptions, Source={StaticResource proxy}}"
SelectedItemBinding="{Binding AssetDescription}">
</DataGridComboBoxColumn>