for (int i = 1; i <= 7; i++)
            {
                for (int j = 1; j <= 10; j++)
                {
                    btn = new Button();
                    btn.Location = new System.Drawing.Point(j * 60, i * 40);
                    btn.Name = "btn" + i.ToString() + j.ToString();
                    btn.Size = new System.Drawing.Size(55, 35);
                    btn.Text = Convert.ToString(i + 1) + "-" + Convert.ToString(j);
                    this.panel1.Controls.Add(btn);
                    btn.ContextMenuStrip = this.contextMenuStrip2;
                    btn.Click += new System.EventHandler(this.button1_Click);
                 }
             }
//获取btn的文字,跳转到令一个窗体        
 private void 结账ToolStripMenuItem_Click(object sender, EventArgs e)
   {
string id;
id=this.btn.text;
Frmsettle frmsettle=new Frmsettle(string id);
frmsettle.show();
   } 这是一个餐桌的平面分布图,当鼠标移到该按钮btn时,右击鼠标,在ToolStripMenuItem选择结账获取btn的餐桌编号,然后跳到结账的窗体,在把获取的餐桌编号显示在结账窗体。
但是这样写:
string id;
id=this.btn.text;
Frmsettle frmsettle=new Frmsettle(string id);
frmsettle.show();
始终获取的是最后一张餐桌号,这是为什么?
网上有人说:
判断是否还有座位,如果有
作为总数-1,然后再取号。我都不懂怎么写,有知道的麻烦写下具体代码。
谢谢

解决方案 »

  1.   

    string id;
    id=this.btn.text;==》        void button1_Click(object sender, EventArgs e)
            {
                Button btnTmp = sender as Button;
                string id;
                id = btnTmp.Text;
            }
      

  2.   

    能看一下 button1_Click 这个方法吗?
    按我的理解应该是,这个方法应该至少做以下事情
    protected void button1_Click(object sender, EventArgs e){
        this.btn = (Button)sender;
    }
      

  3.   

    Button btn = sender. Parent as Button
    if(btn != null)

    string id;
                id = btn .Text;
    }
      

  4.   

    试了下都不行,提示
    无法将类型为“System.Windows.Forms.ToolStripMenuItem”的对象强制转换为类型“System.Windows.Forms.Button”。
      

  5.   

     结账ToolStripMenuItem_Click方法是响应ToolStripMenuItem.Click事件的, 你的事件源是Button.
     
                        btn.ContextMenuStrip = this.contextMenuStrip2;
                        btn.Click += new System.EventHandler(this.button1_Click);大概是因为你给Button的ContextMenuStrip属性指定了指定了contextMenuStrip2,导致在Button的Click事件触发前先触发了contextMenuStrip2的Click事件吧.
      

  6.   

    解决起来很简单,而且跟控件无关。关键是要把这当作一种模式认真研究。你的问题可以归结为这样的模式化问题:“你不知道当初定义一个事件监听时如何给它也传递当时的环境变量值”。其实可以定一个用来通讯的独立的类型,类似于:public class MyIdEventContainer
    {
      public string id;  public void button_Click(object sender, EventArgs e)
       {
            Frmsettle frmsettle=new Frmsettle(this.id);
            frmsettle.show();
            ......
       } 
    }
    for (int i = 1; i <= 7; i++)
                {
                    for (int j = 1; j <= 10; j++)
                    {
                        btn = new Button();
                        btn.Location = new System.Drawing.Point(j * 60, i * 40);
                        btn.Name = "btn" + i.ToString() + j.ToString();
                        btn.Size = new System.Drawing.Size(55, 35);
                        btn.Text = Convert.ToString(i + 1) + "-" + Convert.ToString(j);
                        this.panel1.Controls.Add(btn);
                        btn.ContextMenuStrip = this.contextMenuStrip2;
                        MyIdEventContainer cn= new MyIdEventContainer();
                        cn.id= btn.Text;
                        btn.Click += new System.EventHandler(cn.button_Click);
                     }
                 }
    当然,只要是你的button_click还需要更多的环境参数,比如说需要记录出发事件的Form对象实例,你就可以在这个类型中定义好接口来接收,并且在for循环中记录下参数。
      

  7.   

    顺便可以多说一点。其实如果你使用c#3.0以后的语法(即使是编写.net2.0目标平台的程序也可以使用),其实不定义自定义的类型,而使用匿名委托写法也是可以的,例如:for (int i = 1; i <= 7; i++)
                {
                    for (int j = 1; j <= 10; j++)
                    {
                        btn = new Button();
                        btn.Location = new System.Drawing.Point(j * 60, i * 40);
                        btn.Name = "btn" + i.ToString() + j.ToString();
                        btn.Size = new System.Drawing.Size(55, 35);
                        btn.Text = Convert.ToString(i + 1) + "-" + Convert.ToString(j);
                        this.panel1.Controls.Add(btn);
                        btn.ContextMenuStrip = this.contextMenuStrip2;
                        btn.Click += (s,e)=>
                        {
                            Frmsettle frmsettle=new Frmsettle(btn.Text);
                            frmsettle.show();
                            ......
                        }
                     }
                 }只要使用高版本的vs开发工具,即使开发.net2.0目标平台的程序,也是一样可以使用匿名委托、lamda表达式等语法的。其实c#编译器的处理给我上面给你说的自定一个类型的写法是一模一样的,也就是说它知道这个匿名委托中用到了外部的btn.Text引用,所以就会自动生成一个上面的自定义类型的id参数定义。而且这样写起来更加简单。但是对于那些顽固地不去使用高版本vs的人,因为它的编译器不支持匿名委托、lamda表达式等语法,那么就使用我上面说的自定义类型的写法,也是可以实现参数化地事件监听。
      

  8.   

    还是那个错误么?你把定制每个button右键菜单的那句话放到button单机事件触发的方法中……
    当然了 这样可能需要右击两次你的button才能出现右键菜单
      另外你的这个btn.Click += new System.EventHandler(this.button1_Click);
    this.button1_Click这个方法中干啥了?
      

  9.   

    设个全局btn变量,右击时根据坐标找到对应的按钮赋值给btn,点击菜单时操作btn
      

  10.   

    应该在点击按钮时用一个全局变量记下这个当前的BUTTON.而不是用this.btn