2016-10-26 7 views
0

私は動的にツリーを生成しています(TreeViewItem)。ツリー内の各アイテムに同じコンテキストメニューを追加します。すべてのコンテキストメニューが同じになるので、私は1つを作ってにそれぞれ適用できると考えました。 (おそらくこれは悪い考えです)Clickハンドラがコンテキストメニューが開かれたTreeViewItemを把握できる限り、このように動作するはずです。Clickハンドラが右クリックされたアイテムを知っているコンテキストメニューをプログラムで追加します。

私が(プログラム的結合を追加する)SO here(右クリックしたオブジェクトを取得)し、hereから回答を組み合わせる試み、これを思い付いた:それはとのラインに到達したときに、実行時に

ContextMenu carContextMenu; 

public MainWindow() 
{ 
    InitializeComponent(); 
    Initialize(); 
    ConstructTree(); 
} 

void ConstructTree() 
{ 
    string[] carNames = {"Mustang", "Viper", "Jetta"}; 

    foreach (string car in carNames) 
    { 
     TreeViewItem carNode = new TreeViewItem(); 
     carNode.Header = car; 
     carNode.ContextMenu = carContextMenu; 

     CarTree.Items.Add(carNode); 
    } 
} 

void Initialize() 
{ 
    carContextMenu= new ContextMenu(); 
    MenuItem newQuery = new MenuItem(); 
    newQuery.Header = "Drive car..."; 

    Binding b = new Binding("Parent"); 
    b.RelativeSource = RelativeSource.Self; 

    newQuery.SetBinding(MenuItem.CommandParameterProperty, b); 
    newQuery.Click += NewQuery_Click; 

    carContextMenu.Items.Add(newQuery); 
} 

void NewQuery_Click(object sender, RoutedEventArgs e) 
{ 
    MenuItem mi = sender as MenuItem; 
    if (mi != null) 
    { 
     ContextMenu cm = mi.CommandParameter as ContextMenu; // ***** 
     if (cm != null) 
     { 
      TreeViewItem node = cm.PlacementTarget as TreeViewItem; 
      if (node != null) 
      { 
       Console.WriteLine(node.Header); // car name, ideally 
      } 
     } 
    } 
} 

アスタリスク、mi.CommandParameterはnullなので、残りのメソッドはスキップします。私のアプローチはどうなっていますか?正直なところ、右クリックされた項目は、イベントハンドラ引数の本質的な部分ではなく、何がクリックされたのかを知りたいと思っていることを考えると、少し驚いています。ツリー項目は、右クリックされたときには選択する必要はありません。そのため、信頼できる方法ではないことを確認するだけでなく、ちょっとハッキリな回避策になります。

ありがとうございます!

+0

「送信者」を使用して、クリックされたオブジェクトの名前を判断したり取得する方法は、あなたがよく知っていますか? – MethodMan

+0

私はそうは思いませんか?私は 'MenuItem'(' sender'の型)のプロパティを歩き、有用なものを見つけませんでした。 RoutedEventArgsと同じです。たぶん、同じ 'ContextMenu'オブジェクトを複数の' TreeViewItems'につけているということは、何かを混乱させるでしょうか? – Benjin

+0

あなたは私がこれを行う名前である送信者IDをチェックすることができます。これは、現在実行中のすべてのメニュー項目を同じイベントに配線してクリックした後、スイッチ/ケースを使用してどのメニューアイテムがクリックされた – MethodMan

答えて

0

当然ながら、私は物事を過度に作り出していて、私が従っていたリンクは間違っているか、期限切れであるか、(ほとんどの場合)自分のシナリオの一部を誤読していました。実際には私に応えてください。

私はMenuItemにバインディングを必要とせず、単に全体としてmyMenuItem.Parent.PlacementTargetを見ていたはずです。以下の作業コード:

void Initialize() 
{ 
    carContextMenu= new ContextMenu(); 
    MenuItem newQuery = new MenuItem(); 
    newQuery.Header = "Drive car..."; 

    newQuery.Click += NewQuery_Click; 

    carContextMenu.Items.Add(newQuery); 
} 

void NewQuery_Click(object sender, RoutedEventArgs e) 
{ 
    MenuItem mi = sender as MenuItem; 
    if (mi != null) 
    { 
     ContextMenu cm = mi.Parent as ContextMenu; 
     if (cm != null) 
     { 
      TreeViewItem node = cm.PlacementTarget as TreeViewItem; 
      if (node != null) 
      { 
       Console.WriteLine(node.Header); 
      } 
     } 
    } 
}