Question

I'm struggling with a WPF DependencyProperty / ViewModel binding problem.

I have this class as a helper class for a treeview:

public class TreeViewHelper : DependencyObject
{
    private static readonly Dictionary<DependencyObject, TreeViewSelectedItemBehavior> Behaviors = new Dictionary<DependencyObject, TreeViewSelectedItemBehavior>();

    public static object GetSelectedItem(DependencyObject obj)
    {
        return obj.GetValue(SelectedItemProperty);
    }

    public static void SetSelectedItem(DependencyObject obj, object value)
    {
        obj.SetValue(SelectedItemProperty, value);
    }

    // Using a DependencyProperty as the backing store for SelectedItem.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty SelectedItemProperty =
        DependencyProperty.RegisterAttached("SelectedItem", typeof(object), typeof(TreeViewHelper), new UIPropertyMetadata(null, SelectedItemChanged));

    private static void SelectedItemChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
    {
        if (!(obj is TreeView))
            return;

        if (!Behaviors.ContainsKey(obj))
            Behaviors.Add(obj, new TreeViewSelectedItemBehavior(obj as TreeView));

        var view = Behaviors[obj];
        view.ChangeSelectedItem(e.NewValue);


    }

    private class TreeViewSelectedItemBehavior
    {
        readonly TreeView _view;
        public TreeViewSelectedItemBehavior(TreeView view)
        {
            _view = view;
            view.SelectedItemChanged += (sender, e) => SetSelectedItem(view, e.NewValue);
        }

        internal void ChangeSelectedItem(object p)
        {
            var item = (TreeViewItem)_view.ItemContainerGenerator.ContainerFromItem(p);
            if(item != null) item.IsSelected = true;
        }
    }
}

And my Treeview works this way:

<TreeView 
                        SelectedValuePath="Id" 
                        DataContext="{Binding Path=TreeViewModel}" 
                        ItemsSource="{Binding Items}" 
                        Background="{StaticResource SliderThumbBackgroundBrush}" 
                        helpers:TreeViewHelper.SelectedItem="{Binding Path=Items, Mode=TwoWay}">

And it all works fine, but my challenge is, how Do I manage to let my viewmodel know when the DependencyProperty changes ?

Thanks in advance.

Was it helpful?

Solution

Change UIPropertyMetadata

public static readonly DependencyProperty SelectedItemProperty =
        DependencyProperty.RegisterAttached("SelectedItem", typeof(object), typeof(TreeViewHelper), new UIPropertyMetadata(null, SelectedItemChanged));

to FrameworkPropertyMetadata

public static readonly DependencyProperty SelectedItemProperty =
        DependencyProperty.RegisterAttached("SelectedItem", typeof(object), typeof(TreeViewHelper), new FrameworkPropertyMetaData(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, SelectedItemChanged));
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top