Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/323.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 通过toolstripmenuitem eventhandler获取控件(treeView)_C#_Controls_Contextmenustrip_Ownership - Fatal编程技术网

C# 通过toolstripmenuitem eventhandler获取控件(treeView)

C# 通过toolstripmenuitem eventhandler获取控件(treeView),c#,controls,contextmenustrip,ownership,C#,Controls,Contextmenustrip,Ownership,与这个问题类似: 除了现在我需要找到当单击ToolStripMenuItem时其上下文菜单已打开的对象 SourceControl、Parent、Owner和GetParentControl()都返回null 最初我有一个TreeView,并且设置了ContextMenuStrip属性 这是我的初步代码: ToolStripMenuItem tsmi = (ToolStripMenuItem)sender; ToolStripMenuItem tsmip = (

与这个问题类似:

除了现在我需要找到当单击
ToolStripMenuItem
时其上下文菜单已打开的对象

SourceControl
Parent
Owner
GetParentControl()
都返回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
eventhandler中工作

表格1.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;
}
}
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());
    }
}
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用System.Windows.Forms;
命名空间TestWFA
{
静态类程序
{
/// 
///应用程序的主要入口点。
/// 
[状态线程]
静态void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(新Form1());
}
}
}

不幸的是,我不知道任何上传文件的方法。我尝试将它们作为IMG上传,但没有成功。

假设您已将ContextMenuStrip设置为TreeView。您可以很容易地从
ContextMenuStrip
Opened
处理程序中控制触发哪个菜单:

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:在real app中,你不应该使用像
(发送者作为ContextMenuStrip)这样的结构因为可能存在空指针。您应该在每次强制转换后检查null

[编辑]
好了,现在我明白你的目的了。
处理菜单项<代码>发送方时,对象指向项目触发事件。要找出弹出关联菜单的控件,您应该做三件事:

  • 查找根项目。很可能,单击的项是另一项或更深项的子项
  • 从根项目中,您应该找到ContextMenuStrip对象
  • 从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;
    }
    
    [EDIT2]
    事实证明,这个问题早就讨论过了()。单击根项时,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;
    }
    

    在链接的问题中,私有字段有变通方法,但是标记属性对我来说是习惯性的

    上下文菜单是在TreeView控件中设置的还是在TreeView的每个节点中设置的?我相信它是为TreeView设置的。从那里您可以获得selectedNode。谢谢。请参阅问题的更新部分。我的问题是从toolstripmenuitem事件处理程序执行此操作。谢谢。不幸的是,由于menuObject的SourceControl属性仍然为null,因此仍然无法获取treeView。(我不得不修改代码,但只有一点点,才能让它生成。)(对不起,我是说它是生成的,但我想ContextMenuStrip的情况有点不对劲。)@user420667:你能提供事件处理程序的完整源代码吗?无法理解为什么会得到空引用,因此,我更新了以显示代码。有没有更简单的方法?也许可以聊天?正在将文件上载到堆栈溢出以便显示?
    private void toolStripMenuItem1_Click(object sender, EventArgs e)
    {
      TreeView tv = GetSourceControl(sender) as TreeView;
    
      if (tv != null)
      {
        tv.Nodes.Add("Tree event catched!");
      }
    }
    
    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;
    }