Reputation: 1221
I want to bind a DataGridComboBoxColumn
to a property in the model which is another model where i face either one of two problems:
Form after app is started (this is an example app to demonstrate the problem, the real app only has one Vat-Column)
VatCombo1 does not show the value of the Vat property
VatCombo2 does not show the value of the Vat property
VatCombo3 shows the value of the Vat property correctly
Form after value of VatCombo1 has been changed to 19 --> VatId and VatRate are shown correctly
Form after the value VatCombo3 has been changed to 19 --> VatRate is not updated
How can I get to the ´DataGridComboBoxColumn´ to work? I.e. show the initial value stored in the model property, and change the value when another item is selected from the Combobox
to the right Id AND Rate?
Idealley VatCombo1 approach to show the value on inital load?
Property in the model
private VatModel vat;
public VatModel Vat
{
get { return vat; }
set
{
vat = value;
OnPropertyChanged(new PropertyChangedEventArgs(nameof(Vat)));
}
}
Viewmodel
public ViewModel()
{
VatList.Add(new VatModel(1, 0.00));
VatList.Add(new VatModel(2, 7.00));
VatList.Add(new VatModel(3, 19.00));
VatModel receiptItemVat = new VatModel(2, 7.00);
ReceiptItemModel receiptItem = new ReceiptItemModel(1, receiptItemVat);
ReceiptModel receipt = new ReceiptModel();
receipt.Id = 10;
receipt.Items.Add(receiptItem);
Receipt = receipt;
}
Xalm
<Window x:Class="datagridcombo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:datagridcombo"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Window.DataContext>
<local:ViewModel/>
</Window.DataContext>
<Window.Resources>
<CollectionViewSource Source="{Binding VatList}" x:Key="VatListRes"/>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="50"/>
<RowDefinition/>
</Grid.RowDefinitions>
<Label Content="{Binding Receipt.Id}"/>
<DataGrid ItemsSource="{Binding Receipt.Items}" Grid.Row="1" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Header="ReceiptItemId" Binding="{Binding Id}" Width="80"/>
<DataGridTextColumn Header="VatId" Binding="{Binding Vat.Id}" Width="80"/>
<DataGridTextColumn Header="VatRate" Binding="{Binding Vat.Rate}" Width="80"/>
<!-- Initial value not shown, Property update works -->
<DataGridComboBoxColumn Header="VatCombo1"
ItemsSource="{Binding Source={StaticResource VatListRes}}"
SelectedItemBinding="{Binding Vat, UpdateSourceTrigger=PropertyChanged}"}"
DisplayMemberPath="Rate"
/>
<!-- Initial value not shown, Property update when Enter is hit -->
<DataGridComboBoxColumn Header="VatCombo2"
ItemsSource="{Binding Source={StaticResource VatListRes}}"
SelectedValuePath="Id"
DisplayMemberPath="Rate"
/>
<!-- Initial value not shown, Property not updated -->
<DataGridComboBoxColumn Header="VatCombo3"
ItemsSource="{Binding Source={StaticResource VatListRes}}"
SelectedValueBinding="{Binding Vat.Id, UpdateSourceTrigger=PropertyChanged}"
SelectedValuePath="Id"
DisplayMemberPath="Rate"
/>
</DataGrid.Columns>
</DataGrid>
</Grid>
</Window>
Upvotes: 0
Views: 42
Reputation: 28968
When linking objects always make sure you are using the same reference. In your case you are linking the selected item to the items source of the ComboBox
, but the initial value's instance is not part of the ComboBox.ItemsSource
. So the ComboBox
doesn't select anything. ComboBox
or ItemsControl
in general checks for reference equality too in order to know which item to select when SelectedItem
is set.
To fix this, initialize the selected value with an instance of the ItemsSource
:
public ViewModel()
{
VatList.Add(new VatModel(1, 0.00));
var initialSelectedItem = new VatModel(2, 7.00);
VatList.Add(initialSelectedItem);
VatList.Add(new VatModel(3, 19.00));
VatModel receiptItemVat = initialSelectedItem;
ReceiptItemModel receiptItem = new ReceiptItemModel(1, receiptItemVat);
ReceiptModel receipt = new ReceiptModel();
receipt.Id = 10;
receipt.Items.Add(receiptItem);
Receipt = receipt;
}
Upvotes: 1