2016-07-05 14 views
0

Ich habe eine Attached-Eigenschaft namens TreeViewSelectedItem. Ohne auf zu viele Details einzugehen, warum ich diese angefügte Eigenschaft benötige, werde ich sagen, dass es damit zu tun hat, verschiedene Eigenschaften auf meiner VM zu aktualisieren, basierend auf welcher Art von Element in der TreeView ausgewählt wird.Den Wert einer Eigenschaft innerhalb einer Attached-Eigenschaft festlegen

Mein Problem ist, ich kann nicht scheinen, meinen Code zu erhalten, um die Eigenschaft auf der VM zu aktualisieren.

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> 

Mein Befestigt Eigentum:

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); 
     } 

    } 

Am unteren Ende, ich habe eine Reihe von verschiedenen Möglichkeiten versucht, ein Update zu versuchen, was auch immer die angefügte Eigenschaft gebunden ist, aber Es scheint die Set-Methode der VM-Eigenschaft nicht zu treffen (trifft den Breakpoint nicht).

Wie aktualisiere ich diese Eigenschaft?

+0

Nur ein freundlicher Kommentar: Wenn Sie ein Ereignis abonnieren, vergessen Sie nicht, unsubscibe. Um dich zu fragen. Es ist wahrscheinlich einfacher, eine Klasse zu erstellen, die von Treeview abgeleitet wurde und die 'SelectedItem'-Eigenschaft – lokusking

+0

@lokusking überschreibt, ein guter Haken beim Abmelden. Das ist nur Testcode, also habe ich mir keine Sorgen gemacht, aber für jeden, der darauf schaut, ist es wirklich wichtig, NICHT wegzulassen! Und Sie haben recht, es könnte an dieser Stelle einfacher sein, TreeView zu untergliedern. –

+0

Das lustige ist, Treeview als diese Eigenschaft, noch nicht gelesen. [This] (http://stackoverflow.com/questions/1000040/data-binding-to-selecteitem-in-a-wpf-treeview) könnte Ihnen bei weiteren Entscheidungen helfen – lokusking

Antwort

0

Wie sich herausstellte, war die Lösung 1: SetTreeViewSelectedItem(tree, tree.SelectedItem); (die ich auskommentiert hatte) und 2: verwenden Sie Mode = TwoWay in der Bindung.

Ich werde feststellen, dass der andere Ansatz zu adressieren, was ich versuche, hier zu erreichen, ist die IsSelected-Eigenschaft der TreeView und binden Sie es an einige boolesche Eigenschaft auf den zugrunde liegenden VMs. Darauf wurde von einigen Leuten hingewiesen (wie Julien und Maverik). Während ich es in meiner ganz speziellen Situation nicht verwenden konnte, ist dies der Weg in 99,9% der Situationen zu gehen.