Update:
I successfully enable to update property by change value in the textbox. But for the combobox I am still confused. I update the code so that might help to illustrate my confusion.
class viewModelObj:INotifyPropertyChanged
{
public string displayName { get; set; }
public Dictionary<string,string> generalNote { get; set; }
private int _weight;
public int Weight
{
get { return _weight; }
set
{
_weight = value;
OnPropertyChanged("Weight");
MessageBox.Show($"Weight changed from model.");
}
}
private string _material;
public string Material
{
get { return _material; }
set
{
_material = value;
OnPropertyChanged("Material");
MessageBox.Show($"Material changed from model.");
}
}
public viewModelObj(string name)
{
displayName = name;
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged([CallerMemberName] string propertyName = "")
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion
}
XAML:
<ListBox x:Name="catDocListView" Grid.Column="0" Grid.RowSpan="2" Margin="16" ItemContainerStyle="{StaticResource ContainerStyle}" ItemsSource="{Binding viewModelSource}" DisplayMemberPath="displayName">
</ListBox>
<ComboBox x:Name="materialCombo" Grid.Column="1" HorizontalAlignment="Stretch" Margin="8" ItemsSource="{Binding viewModelSource}" SelectedItem="{Binding viewModelObj}">
<ComboBoxItem>ABC</ComboBoxItem>
<ComboBoxItem>DEF</ComboBoxItem>
<ComboBoxItem>XYZ</ComboBoxItem>
</ComboBox>
<TextBox Grid.Row="1" Grid.Column="2" BorderBrush="Black" Text="{Binding ElementName=catDocListView, Path=SelectedItem.Weight, Mode=TwoWay}"/>
<DataGrid x:Name="generalNoteDG" CanUserAddRows="False" AutoGenerateColumns="False" ItemsSource="{Binding generalNoteSource}">
<DataGrid.Columns>
<DataGridCheckBoxColumn/>
<DataGridTextColumn Header="Note" Binding="{Binding note}" Width="Auto"/>
<DataGridTextColumn Header="No" Binding="{Binding no}" Width="Auto"/>
<DataGridTextColumn Header="English Note" Binding="{Binding eng}" Width="Auto"/>
<DataGridTextColumn Header="German Note" Binding="{Binding deu}" Width="Auto"/>
</DataGrid.Columns>
</DataGrid>
The viewModelSource is a ObservableCollection of viewModelObj class.
If you check the TextBox tag you will understand. Assuming I have now two items in the ListBox, I select the first one and the corresponding textbox shows the value of Weight property. I update the textbox then the value is also updated. After I select the second item and switch back to the first item, the value shown in the textbox should be the already updated one.
I want the same feature to the combobox.
Original Post
I try to explain the question more clearly because I think it is little tricky.
Let's say we have a Listbox
that displays all possible items, a Combobox
that displays available item which are independant to any other value, a Textbox
and a Datagrid
that shows preloaded values which are also independant to any other value, in a GUI page.
A class viewModelObj
has some properties corresponding to the Combobox
, Textbox
and Datagrid
. A ObservableCollection
contains several such classes.
I now one-way bind the ObservableCollection
to the Listbox
. No matter which item I choose in the Listbox
, the available items in the Combobox
and values in the Datagrid
should remain unchanged. But when I make the selection in Combobox
and Datagrid
(it has a checkbox column), the corresponding property of the viewModelObj
class should be changed/added (at the beginning they are null).
XAML:
<ListBox x:Name="catDocListView" Grid.Column="0" Grid.RowSpan="2" Margin="16" ItemContainerStyle="{StaticResource ContainerStyle}" ItemsSource="{Binding}" DisplayMemberPath="displayName">
</ListBox>
<ComboBox x:Name="materialCombo" Grid.Column="1" HorizontalAlignment="Stretch" Margin="8" ItemsSource="{Binding viewModelSource}" SelectedItem="{Binding viewModelObj}">
<ComboBoxItem>ABC</ComboBoxItem>
<ComboBoxItem>DEF</ComboBoxItem>
<ComboBoxItem>XYZ</ComboBoxItem>
</ComboBox>
<TextBox Grid.Row="1" Grid.Column="2" BorderBrush="Black"></TextBox>
<DataGrid x:Name="generalNoteDG" CanUserAddRows="False" AutoGenerateColumns="False" ItemsSource="{Binding generalNoteSource}">
<DataGrid.Columns>
<DataGridCheckBoxColumn/>
<DataGridTextColumn Header="Note" Binding="{Binding note}" Width="Auto"/>
<DataGridTextColumn Header="No" Binding="{Binding no}" Width="Auto"/>
<DataGridTextColumn Header="English Note" Binding="{Binding eng}" Width="Auto"/>
<DataGridTextColumn Header="German Note" Binding="{Binding deu}" Width="Auto"/>
</DataGrid.Columns>
</DataGrid>
The viewModelSource and generalNoteSource are all in the viewModel.cs
As you can see, the Datagrid source binds to another List and the availble items in the Combobox are given manuelly. When I try to bind the itemsource of the Combobox to the ObservableCollection of the viewModelObj, an error pops up.
System.Windows.Markup.XamlParseException: ''Add value to collection of type 'System.Windows.Controls.ItemCollection' threw an exception.'
The viewModelObj:
class viewModelObj
{
public string displayName { get; set; }
public string material { get; set; }
public int weight { get; set; }
public Dictionary<string,string> generalNote { get; set; }
public viewModelObj(string name)
{
displayName = name;
}
}
The display property shows item in Listbox, material refers to the combobox and the generalNote corresponds to the value selected in the datagrid.
Now I'm confused how to use two-way binding to get selected values in the combobox, datagrid and textbox with predefined values.
Hope I explain the question clear.
Could someone give me a hint?