I have a view which wraps a TreeView
, called MbiTreeView
. I want to get the selected item from the (wrapped) tree view in the view model.
The 'parent' user control which uses this custom user control:
<UserControl [...]>
<views:MbiTreeView
Grid.Row="0"
cal:Bind.Model="{Binding TreeViewModel}"
SelectedItem="{Binding SelectedItem}">
</views:MbiTreeView>
</UserControl>
The parent user control is bound to this view model:
internal sealed class SomeViewModel : PropertyChangedBase
{
public object SelectedItem
{
get => _selectedItem;
set
{
_selectedItem = value;
NotifyOfPropertyChange(() => SelectedItem);
}
}
public IMbiTreeViewModel TreeViewModel { get; }
public SomeViewModel(
IMbiTreeViewModel treeViewModel)
{
TreeViewModel = treeViewModel;
}
}
The MbiTreeView user control is rather straight forward. It subscribes to the selection changed event, and defines a few templates (not relevant for this question, so left them out in the question)
<TreeView ItemsSource="{Binding Items}" SelectedItemChanged="TreeView_OnSelectedItemChanged">
iew.ItemContainerStyle>
The code behind declares the dependency property:
public partial class MbiTreeView
{
public static readonly DependencyProperty SelectedItemProperty = DependencyProperty.Register(
nameof(SelectedItem),
typeof(object),
typeof(MbiTreeView),
null);
public object SelectedItem
{
get => GetValue(SelectedItemProperty);
set => SetValue(SelectedItemProperty, value);
}
public MbiTreeView()
{
InitializeComponent();
}
private void TreeView_OnSelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
{
SelectedItem = e.NewValue;
}
}
when I start the application, I can navigate through the tree view items. When I click on a treeview node, then the OnSelectedItemChanged
event fires (I get into my breakpoint there). So everything goes fine up and until setting the value in the dependency property SelectedItem
.
Then I would expect that the xaml binding gets notified, and updates the view model. But that never happens.
I am getting nowhere with this, help is greatly appreciated.
The SelectedItem Binding should be TwoWay:
<views:MbiTreeView ...
SelectedItem="{Binding SelectedItem, Mode=TwoWay}"/>
You could declare the property like shown below to make to bind TwoWay by default.
public static readonly DependencyProperty SelectedItemProperty =
DependencyProperty.Register(
nameof(SelectedItem),
typeof(object),
typeof(MbiTreeView),
new FrameworkPropertyMetadata(
null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));