2011-06-12 67 views
2

與此類似問題的控制(TreeView控件): get contextmenustrip from toolstripmenuitem獲得由toolstripmenuitem事件處理

只是現在我需要找到其上下文菜單中點擊ToolStripMenuItem時打開的對象。

SourceControlParent,OwnerGetParentControl()都返回null。

最初我有一個TreeView,它的ContextMenuStrip屬性被設置。

這裏是我的初步代碼:

 ToolStripMenuItem tsmi = (ToolStripMenuItem)sender; 
     ToolStripMenuItem tsmip = (ToolStripMenuItem)tsmi.OwnerItem; 
     ContextMenuStrip cms = (ContextMenuStrip)tsmip.GetCurrentParent(); 
     TreeView tv = (TreeView)cms.SourceControl; 
     // returns null, but not in the cms_openHandler 
     tv.Nodes.Add(new TreeNode("event fired.")); 

我是否獲得了ContextMenuStrip不當?爲什麼cms的SourceControl屬性在OpenHandler中工作,但不是來自ToolStripMenuItem事件處理程序?

Form1.Designer.cs:

namespace TestWFA 
{ 
partial class Form1 
{ 
    /// <summary> 
    /// Required designer variable. 
    /// </summary> 
    private System.ComponentModel.IContainer components = null; 

    /// <summary> 
    /// Clean up any resources being used. 
    /// </summary> 
    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> 
    protected override void Dispose(bool disposing) 
    { 
     if (disposing && (components != null)) 
     { 
      components.Dispose(); 
     } 
     base.Dispose(disposing); 
    } 

    #region Windows Form Designer generated code 

    /// <summary> 
    /// Required method for Designer support - do not modify 
    /// the contents of this method with the code editor. 
    /// </summary> 
    private void InitializeComponent() 
    { 
     this.components = new System.ComponentModel.Container(); 
     this.treeView1 = new System.Windows.Forms.TreeView(); 
     this.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip(this.components); 
     this.expandToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 
     this.childrenToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 
     this.allDescendantsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 
     this.collapseToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 
     this.childrenToolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem(); 
     this.parentToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 
     this.childrenToolStripMenuItem2 = new System.Windows.Forms.ToolStripMenuItem(); 
     this.allDescendantsToolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem(); 
     this.contextMenuStrip1.SuspendLayout(); 
     this.SuspendLayout(); 
     // 
     // treeView1 
     // 
     this.treeView1.ContextMenuStrip = this.contextMenuStrip1; 
     this.treeView1.Location = new System.Drawing.Point(64, 75); 
     this.treeView1.Name = "treeView1"; 
     this.treeView1.Size = new System.Drawing.Size(262, 247); 
     this.treeView1.TabIndex = 0; 
     // 
     // contextMenuStrip1 
     // 
     this.contextMenuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { 
     this.expandToolStripMenuItem, 
     this.collapseToolStripMenuItem}); 
     this.contextMenuStrip1.Name = "contextMenuStrip1"; 
     this.contextMenuStrip1.Size = new System.Drawing.Size(153, 70); 
     this.contextMenuStrip1.Opening += new System.ComponentModel.CancelEventHandler(this.contextMenuStrip1_Opening); 
     // 
     // expandToolStripMenuItem 
     // 
     this.expandToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { 
     this.childrenToolStripMenuItem, 
     this.allDescendantsToolStripMenuItem}); 
     this.expandToolStripMenuItem.Name = "expandToolStripMenuItem"; 
     this.expandToolStripMenuItem.Size = new System.Drawing.Size(152, 22); 
     this.expandToolStripMenuItem.Text = "Expand"; 
     // 
     // childrenToolStripMenuItem 
     // 
     this.childrenToolStripMenuItem.Name = "childrenToolStripMenuItem"; 
     this.childrenToolStripMenuItem.Size = new System.Drawing.Size(161, 22); 
     this.childrenToolStripMenuItem.Text = "Children"; 
     this.childrenToolStripMenuItem.Click += new System.EventHandler(this.childrenToolStripMenuItem_Click); 
     // 
     // allDescendantsToolStripMenuItem 
     // 
     this.allDescendantsToolStripMenuItem.Name = "allDescendantsToolStripMenuItem"; 
     this.allDescendantsToolStripMenuItem.Size = new System.Drawing.Size(161, 22); 
     this.allDescendantsToolStripMenuItem.Text = "All Descendants"; 
     this.allDescendantsToolStripMenuItem.Click += new System.EventHandler(this.allDescendantsToolStripMenuItem_Click); 
     // 
     // collapseToolStripMenuItem 
     // 
     this.collapseToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { 
     this.childrenToolStripMenuItem1, 
     this.parentToolStripMenuItem, 
     this.childrenToolStripMenuItem2, 
     this.allDescendantsToolStripMenuItem1}); 
     this.collapseToolStripMenuItem.Name = "collapseToolStripMenuItem"; 
     this.collapseToolStripMenuItem.Size = new System.Drawing.Size(152, 22); 
     this.collapseToolStripMenuItem.Text = "Collapse"; 
     // 
     // childrenToolStripMenuItem1 
     // 
     this.childrenToolStripMenuItem1.Name = "childrenToolStripMenuItem1"; 
     this.childrenToolStripMenuItem1.Size = new System.Drawing.Size(161, 22); 
     this.childrenToolStripMenuItem1.Text = "All Ancestors"; 
     this.childrenToolStripMenuItem1.Click += new System.EventHandler(this.childrenToolStripMenuItem1_Click); 
     // 
     // parentToolStripMenuItem 
     // 
     this.parentToolStripMenuItem.Name = "parentToolStripMenuItem"; 
     this.parentToolStripMenuItem.Size = new System.Drawing.Size(161, 22); 
     this.parentToolStripMenuItem.Text = "Parent"; 
     this.parentToolStripMenuItem.Click += new System.EventHandler(this.parentToolStripMenuItem_Click); 
     // 
     // childrenToolStripMenuItem2 
     // 
     this.childrenToolStripMenuItem2.Name = "childrenToolStripMenuItem2"; 
     this.childrenToolStripMenuItem2.Size = new System.Drawing.Size(161, 22); 
     this.childrenToolStripMenuItem2.Text = "Children"; 
     this.childrenToolStripMenuItem2.Click += new System.EventHandler(this.childrenToolStripMenuItem2_Click); 
     // 
     // allDescendantsToolStripMenuItem1 
     // 
     this.allDescendantsToolStripMenuItem1.Name = "allDescendantsToolStripMenuItem1"; 
     this.allDescendantsToolStripMenuItem1.Size = new System.Drawing.Size(161, 22); 
     this.allDescendantsToolStripMenuItem1.Text = "All Descendants"; 
     this.allDescendantsToolStripMenuItem1.Click += new System.EventHandler(this.allDescendantsToolStripMenuItem1_Click); 
     // 
     // Form1 
     // 
     this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 
     this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 
     this.ClientSize = new System.Drawing.Size(406, 365); 
     this.Controls.Add(this.treeView1); 
     this.Name = "Form1"; 
     this.Text = "Form1"; 
     this.contextMenuStrip1.ResumeLayout(false); 
     this.ResumeLayout(false); 

    } 

    #endregion 

    private System.Windows.Forms.TreeView treeView1; 
    private System.Windows.Forms.ContextMenuStrip contextMenuStrip1; 
    private System.Windows.Forms.ToolStripMenuItem expandToolStripMenuItem; 
    private System.Windows.Forms.ToolStripMenuItem childrenToolStripMenuItem; 
    private System.Windows.Forms.ToolStripMenuItem allDescendantsToolStripMenuItem; 
    private System.Windows.Forms.ToolStripMenuItem collapseToolStripMenuItem; 
    private System.Windows.Forms.ToolStripMenuItem childrenToolStripMenuItem1; 
    private System.Windows.Forms.ToolStripMenuItem parentToolStripMenuItem; 
    private System.Windows.Forms.ToolStripMenuItem childrenToolStripMenuItem2; 
    private System.Windows.Forms.ToolStripMenuItem allDescendantsToolStripMenuItem1; 
} 
} 

Form1.cs中:

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Windows.Forms; 

namespace TestWFA 
{ 
public partial class Form1 : Form 
{ 
    public Form1() 
    { 
     InitializeComponent(); 
     treeView1.Nodes.Add(new TreeNode("root")); 
    } 

    private void childrenToolStripMenuItem1_Click(object sender, EventArgs e) 
    { 
     TreeView tv = GetSourceControl(sender) as TreeView; 

     if (tv != null) 
     { 
      tv.Nodes.Add("Tree event catched!"); 
     } 

     /*ToolStripMenuItem tsmi = (ToolStripMenuItem)sender; 
     ToolStripMenuItem tsmip = (ToolStripMenuItem)tsmi.OwnerItem; 


     ContextMenuStrip cms = (ContextMenuStrip)tsmip.GetCurrentParent(); 
     ToolStrip ts = tsmip.GetCurrentParent(); 

     IContainer c = cms.Container; 
     TreeView tv = (TreeView)c; 
     tv.Nodes.Add(new TreeNode("event fired."));*/ 
    } 

    private object GetSourceControl(object Sender) 
    { 
     if (Sender as ContextMenuStrip != null) 
     { 
      return ContextMenuStrip.SourceControl; 
     } 

     var item = Sender as ToolStripItem; 

     // move to root item 
     while (item.OwnerItem != null) 
     { 
      item = item.OwnerItem; 
     } 

     // we have root item now, so lets take ContextMenuStrip object 
     var menuObject = item.Owner as ContextMenuStrip; 

     if (menuObject != null) 
     { 
      return menuObject.SourceControl; 
     } 

     return null; 

    } 

    private void parentToolStripMenuItem_Click(object sender, EventArgs e) 
    { 

    } 

    private void childrenToolStripMenuItem2_Click(object sender, EventArgs e) 
    { 

    } 

    private void allDescendantsToolStripMenuItem1_Click(object sender, EventArgs e) 
    { 

    } 

    private void childrenToolStripMenuItem_Click(object sender, EventArgs e) 
    { 

    } 

    private void allDescendantsToolStripMenuItem_Click(object sender, EventArgs e) 
    { 
    } 

    private void contextMenuStrip1_Opening(object sender, CancelEventArgs e) 
    { 
     try 
     { 
      ContextMenuStrip cms = (ContextMenuStrip)sender; 

     } 
     catch 
     { 
     } 
     try 
     { 
      TreeView tv = (TreeView)sender; 
     } 
     catch 
     { 
     } 
    } 

} 
} 

的Program.cs:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Windows.Forms; 

namespace TestWFA 
{ 
static class Program 
{ 
    /// <summary> 
    /// The main entry point for the application. 
    /// </summary> 
    [STAThread] 
    static void Main() 
    { 
     Application.EnableVisualStyles(); 
     Application.SetCompatibleTextRenderingDefault(false); 
     Application.Run(new Form1()); 
    } 
} 
} 

不幸的是我不知道的任何方式上傳文件。我嘗試將它們上傳爲imgs,但沒有奏效。

+0

是否上下文菜單中TreeView控件或在TreeView中的每個節點設置? – 2011-06-12 20:09:39

+0

我相信它是爲treeView設置的。從那裏你可以得到selectedNode。 – user420667 2011-06-12 23:25:12

回答

2

假設您將ContextMenuStrip設置爲TreeView。你可以很容易地獲得其菜單是從Opened處理程序觸發您ContextMenuStrip控制:

private void contextMenuStrip1_Opened(object sender, EventArgs e) 
{ 
    TreeView tv = (sender as ContextMenuStrip).SourceControl as TreeView; 
    tv.Nodes.Add("Tree event catched!"); 
} 

如果的ContextMenuStrip被設置爲TreeView的項目這段代碼也將工作。

PS:在真正的應用程序中,您不應該使用像(sender as ContextMenuStrip).SourceControl as TreeView;這樣的構造,因爲可能存在空指針。您應該在每次投射後檢查爲空。

[編輯]
好的,現在我明白你的目標了。
當您處理菜單項sender對象指向項目觸發的事件。要找出彈出上下文菜單的控件,您應該做三件事:

  1. 查找根項目。它的可能性是,被點擊的項目是另一項或更深的項目的子項目。
  2. 從根項目你應該找出的ContextMenuStrip對象
  3. 可以很容易地從的ContextMenuStrip的SourceControl財產找出有趣控制

我寫簡單的方法做一切工作:

/// <summary> 
/// Gets controls for context menu 
/// </summary> 
/// <param name="Sender">Sender object from menu event handler</param> 
/// <returns></returns> 
private object GetSourceControl(Object Sender) 
{ 
    // ContextMenuStrip sended? 
    if (Sender as ContextMenuStrip != null) 
    { 
    ContextMenuStrip cms = Sender as ContextMenuStrip; 
    return cms.SourceControl; 
    } 

    var item = Sender as ToolStripItem; 

    // move to root item 
    while (item.OwnerItem != null) 
    { 
    item = item.OwnerItem; 
    } 

    // we have root item now, so lets take ContextMenuStrip object 
    var menuObject = item.Owner as ContextMenuStrip; 

    if (menuObject != null) 
    { 
    return menuObject.SourceControl; 
    } 

    return null; 
} 

你可以簡單地使用它。例如,我們有菜單項的Click事件處理程序:

private void toolStripMenuItem1_Click(object sender, EventArgs e) 
{ 
    TreeView tv = GetSourceControl(sender) as TreeView; 

    if (tv != null) 
    { 
    tv.Nodes.Add("Tree event catched!"); 
    } 
} 

[EDIT2]
由於原來這個問題很早就discused(SourceControl of ContextMenuStrip is Nothing in ToolStripMenuItem Click?)。當您單擊根項目時,SourceControl屬性不爲null,但如果您單擊子項目,它將等於null。所以解決方案是將SourceControl的值存儲在稍後使用的地方。我建議在Tag屬性中執行此操作。因此,所有的方法將是看起來像:

private void contextMenuStrip1_Opening(object sender, CancelEventArgs e) 
{ 
    contextMenuStrip1.Tag = (sender as ContextMenuStrip).SourceControl; 
} 
.... 

private object GetSourceControl(object Sender) 
{ 
    if (Sender as ContextMenuStrip != null) 
    { 
    return ContextMenuStrip.SourceControl; 
    } 

    var item = Sender as ToolStripItem; 

    // move to root item 
    while (item.OwnerItem != null) 
    { 
    item = item.OwnerItem; 
    } 

    // we have root item now, so lets take ContextMenuStrip object 
    var menuObject = item.Owner as ContextMenuStrip; 

    if (menuObject != null) 
    { 
    return menuObject.Tag; 
    } 

    return null; 
} 

在鏈接的問題有解決辦法了私人領域,但Tag屬性是習慣性的,我

+0

謝謝。請參閱問題的更新部分。我的問題是從toolstripmenuitem事件處理程序執行此操作。 – user420667 2011-06-13 14:59:07

+1

@ user420667:我編輯了我的答案。希望這會有所幫助 – 2011-06-13 17:02:08

+0

謝謝。不幸的是,仍然沒有得到treeView,因爲menuObject的SourceControl屬性仍然是空的。 (我不得不修改代碼,但只有一點點,以使其構建。) – user420667 2011-06-13 17:23:12