2016-07-05 88 views
0

我有一個名爲TreeViewSelectedItem的附加屬性。爲了不涉及爲什麼需要這個附加屬性的太多細節,我會說它必須根據在TreeView中選擇什麼類型的項目來更新我的VM上的不同屬性。設置屬性值從一個附加屬性

我的問題是,我似乎無法讓我的代碼更新VM上的屬性。

XAML中設置:

<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> 

我的附加屬性:

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

    } 

在底部,我已經嘗試了許多不同的方式去嘗試任何這種附加屬性綁定到一個更新,但它似乎沒有擊中VM屬性的Set方法(不會觸及斷點)。

如何更新該屬性?

+0

只是一個友好的評論:如果你訂閱一個事件不要忘了取消補充。給你提問。創建一個從Treeview派生的類並覆蓋'SelectedItem'屬性 – lokusking

+0

@lokusking,可能更容易,很好的接受退訂。這只是測試代碼,所以我並不擔心,但對於任何想要這樣做的人來說,這是非常重要的,不要離開!而且你是對的,在這一點上,子類化TreeView可能會更簡單。 –

+0

有趣的是,Treeview作爲這個屬性,但只讀。 [這](http://stackoverflow.com/questions/1000040/data-binding-to-selecteditem-in-a-wpf-treeview)可能會幫助你進一步desicions – lokusking

回答

0

事實證明,解決方案是1:使用SetTreeViewSelectedItem(tree, tree.SelectedItem);(我已經註釋掉) 和2:在綁定中使用Mode = TwoWay。

我會注意到,另一種解決我在此嘗試完成的方法是使用TreeView的IsSelected屬性並將其綁定到基礎VM上的某個布爾屬性。許多人(如Julien和Maverik)指出了這一點。雖然我不能在我特殊的情況下使用它,但這是99.9%的情況。