简体   繁体   中英

Setting the value of a property from inside of an Attached Property

I have an Attached Property called TreeViewSelectedItem. Without going into too many details of why I need this attached property, I will say it has to do with having to update different properties on my VM based on what type of item is selected in the TreeView.

My problem is, I cannot seem to get my code to update the property on the VM.

The xaml setup:

    <TreeView ItemsSource="{Binding Lists}" l:BindableSelectedItemBehavior.TreeViewSelectedItem="{Binding SelectedListGroup}">

        <ItemsControl.ItemTemplate>
            <HierarchicalDataTemplate ItemsSource="{Binding }" >
                <TextBlock Text="{Binding Key}"/>
                <HierarchicalDataTemplate.ItemTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding Key}"/>
                    </DataTemplate>
                </HierarchicalDataTemplate.ItemTemplate>                    
            </HierarchicalDataTemplate>
        </ItemsControl.ItemTemplate>
    </TreeView>

My Attached Property:

    public static object GetTreeViewSelectedItem(DependencyObject obj)
    {
        return (object)obj.GetValue(TreeViewSelectedItemProperty);
    }

    public static void SetTreeViewSelectedItem(DependencyObject obj, object value)
    {
        obj.SetValue(TreeViewSelectedItemProperty, value);
    }

    // Using a DependencyProperty as the backing store for TreeViewSelectedItem.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty TreeViewSelectedItemProperty =
        DependencyProperty.RegisterAttached("TreeViewSelectedItem", typeof(object), typeof(BindableSelectedItemBehavior), new UIPropertyMetadata(null,
            (s,a) =>
            {
                TreeView tree = s as TreeView;

                if (tree == null)
                    return;

                if (a.NewValue != null)
                {
                    tree.SelectedItemChanged += tree_SelectedItemChanged;
                    tree.SourceUpdated += tree_SourceUpdated;
                }
                else
                {

                }

            }));

    static void tree_SourceUpdated(object sender, System.Windows.Data.DataTransferEventArgs e)
    {
        throw new NotImplementedException();
    }

    static void tree_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
    {
        TreeView tree = sender as TreeView;
        object binding;
        BindingExpression bindingExp;

        if (tree == null)
            return;

        bindingExp = BindingOperations.GetBindingExpression(tree, BindableSelectedItemBehavior.TreeViewSelectedItemProperty);
        binding = GetTreeViewSelectedItem(tree);

        if (binding == null)
            return;

        if (binding.GetType() == e.NewValue.GetType())
        {
            System.Diagnostics.Debug.WriteLine("Type match");
            binding = tree.SelectedItem;
            //tree.SetValue(BindableSelectedItemBehavior.TreeViewSelectedItemProperty, tree.SelectedItem);
            //SetTreeViewSelectedItem(tree, tree.SelectedItem);
            tree.SetCurrentValue(BindableSelectedItemBehavior.TreeViewSelectedItemProperty, tree.SelectedItem);
        }

    }

At the bottom, I have tried a number of different ways to try an update whatever this Attached Property is bound to but it doesn't seem to hit the VM property's Set method (doesn't hit the breakpoint).

How do I update that property?

As it turns out, the solution was 1: to use SetTreeViewSelectedItem(tree, tree.SelectedItem); (which I had commented out) and 2: use Mode=TwoWay in the binding.

I will note that the other approach to addressing what I am trying to accomplish here is to use the IsSelected property of the TreeView and bind it to some boolean property on the underlying VMs. This was pointed out by a number of people (like Julien and Maverik). While I couldn't use it in my very special situation, this is the way to go in 99.9% of the situations.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM