2016-07-05 10 views
0

私はTreeViewSelectedItemという添付プロパティを持っています。私はこの添付プロパティが必要な理由についてあまり詳しく説明しませんが、ツリービューで選択されているアイテムのタイプに基づいて、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' - Property – lokusking

+0

@lokuskingをオーバーライドすると、おそらく簡単です。これは単なるテストコードなので、私はそれを心配していませんでしたが、これを見ている人にとっては、それは絶対に外さないことが重要です!そして、あなたが正しいですが、TreeViewをサブクラス化するのはこの時点で簡単かもしれません。 –

+0

面白いのは、Treeviewはこのプロパティですが、まだ読み込み専用です。 [This](http://stackoverflow.com/questions/1000040/data-binding-to-selecteditem-in-a-wpf-treeview)は、さらなる意欲を助けるかもしれない – lokusking

答えて

0

解決策は1でした。SetTreeViewSelectedItem(tree, tree.SelectedItem);(これは私がコメントしました) と2を使用します:バインディングでMode = TwoWayを使用します。

私がここで達成しようとしていることに対処するもう1つのアプローチは、TreeViewのIsSelectedプロパティを使用して、基になるVMのいくつかのブール値プロパティにバインドすることです。これは多くの人々(JulienやMaverikなど)によって指摘されました。私は非常に特別な状況でそれを使用できませんでしたが、これは99.9%の状況に入る方法です。

関連する問題