In my project, I have a Combobox and a Treeview. A dictionary Dictionary<string, ObservableCollection<ViewItem>>
is the item source of the Combobox, and the DisplayMemberPath
is the Key
. It read existing Json files in a certain directory. The item source of the Treeview is bound to the Combobox and the Path
is SelectedItem.Value
.
Then a button has a command to update the dictionary, basically to add a new entry. I have implemented the INotifyPropertyChanged
interface but the Combobox is not updated after the button is clicked.
The following are the codes:
XAML:
<GroupBox Header="Template" Grid.Column="1" Grid.Row="0" Grid.RowSpan="6" Margin="10,10,10,10">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="10*"/>
</Grid.RowDefinitions>
<ComboBox x:Name="templateCombobox" Grid.Row="0" Margin="5,10,5,10" ItemsSource="{Binding LoadedTemplateViews,Mode=TwoWay,NotifyOnSourceUpdated=True,UpdateSourceTrigger=PropertyChanged}" DisplayMemberPath="Key" SelectedValue="{Binding SelectedItem}" SelectedValuePath="Key"/>
<TreeView Name="templateTreeview"
ItemsSource="{Binding ElementName=templateCombobox, Path=SelectedItem.Value}"
FontSize="14"
Grid.Row="2"
AllowDrop="True" Margin="5,5,5,10">
<i:Interaction.Behaviors>
<local:DragDropBehavior />
</i:Interaction.Behaviors>
<TreeView.ItemContainerStyle>
<Style TargetType="{x:Type TreeViewItem}">
<Setter Property="IsExpanded" Value="True" />
</Style>
</TreeView.ItemContainerStyle>
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type model:ViewItem}" ItemsSource="{Binding Path=ViewItems}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Path=ItemName}" Margin="0,0,10,0" />
<Button Name="DeleteTreeViewItem" Background="Transparent" BorderBrush="Transparent" Click="DeleteTreeViewItem_Click" Visibility="{Binding Path=IsVisible,Converter={StaticResource IntConverter}}">
<Image Source="delete_cross.png" Height="15" />
</Button>
</StackPanel>
</HierarchicalDataTemplate>
</TreeView.Resources>
</TreeView>
</Grid>
</GroupBox>
<Button Content="CREATE" Grid.Column="1" Grid.Row="1" Command="{Binding CreateTemplateJsonCommand}" />
ViewModeBase class
public class ViewModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
Simplified ViewModel, it inherits ViewModelBase:
private Dictionary<string, ObservableCollection<ViewItem>> _loadedTemplateViews;
public Dictionary<string, ObservableCollection<ViewItem>> LoadedTemplateViews
{
get { return _loadedTemplateViews; }
set { _loadedTemplateViews = value; OnPropertyChanged(nameof(LoadedTemplateViews)); }
}
public TemplateViewModel(TemplateDetailsStore templateDetailsStore)
{
LoadedTemplateViews = templateViewUIDataService.TemplatesInfo;
CreateTemplateJsonCommand = new CreateTemplateJsonCommand(templateDetailsStore, this);
}
The templateViewUIDataService.TemplatesInfo
reads local JSON files and returns a dictionary. The key is the filename and the value is the desired data.
Simplified CreateTemplateJsonCommand:
internal class CreateTemplateJsonCommand : CommandBase
{
private readonly TemplateDetailsStore _store;
private readonly TemplateView1Model _viewModel;
public CreateTemplateJsonCommand(TemplateDetailsStore store, TemplateView1Model viewModel)
{
_store = store;
_viewModel = viewModel;
}
public override void Execute(object parameter)
{
_viewModel.LoadedTemplateViews.Add(_viewModel.templateFileName, new ObservableCollection<ViewItem> { _store.currentTemplateDetails.TreeviewDetail } );
}
}
}
Now I click the Create button, and the new entry is added to the item source dictionary, I can see that in debug mode. But the Combobox is not refreshed. I cannot see the created value from the dropdown of the Combobox.
Can someone give me a hint of where I did wrong? Thank you.