2012-03-20 120 views
0

我有一个C#DataGridView显示最多5个定时器的时间。使用DataGridView的MouseClick事件,我可以用选项“Start Timer”和“Stop Timer”创建一个动态的上下文菜单。见下面的代码。C#DataGridView动态上下文菜单

我遇到的麻烦是将动态上下文菜单链接到方法。例如,选择“启动计时器1”时,我需要启动第一个计时器,但“启动计时器2”需要启动另一个计时器。我已经有一个方法(非上下文菜单相关),启动相关的计时器,但我不知道如何链接两个。

我想我需要一个上下文菜单事件,但我有点失落。

任何帮助将是非常有帮助的。

private void dataGridView1_MouseClick(object sender, MouseEventArgs e) 
{  
    if (e.Button == MouseButtons.Right)  
    {   
     ContextMenu m = new ContextMenu();   

     int r = dataGridView1.HitTest(e.X,e.Y).RowIndex; 

     m.MenuItems.Add(new MenuItem("Start Timer " + r.ToString()));   
     m.MenuItems.Add(new MenuItem("Stop Timer " + r.ToString()));   

     m.Show(dataGridView1, new Point(e.X, e.Y));  
    } 
} 

private void StartTimer(int t) 
{ 
    ... code starts the t timer ... 
} 

回答

0

您可以处理MenuItem.Click事件是这样的:

var item = new MenuItem("Start Timer " + r.ToString(); 
item.Click += (sender, e) => this.StartTimer(r); 
m.MenuItems.Add(item) 

或者,如果你想使用MVVM(http://msdn.microsoft.com/en-您可以使用命令和CommandParameters us/library/ms752308.aspx)

+0

谢谢尼古拉。会试试看。 – Jayie 2012-03-20 09:48:22

+0

尼古拉。我确实尝试了上面的代码,但无法使其工作。我了解它背后的想法,所以我已经发布了一个自己的答案与工作版本。虽然非常非常粗糙。 – Jayie 2012-03-20 21:40:33

0

无法获得上述代码工作后,我做了一些更多的研究,现在有一个粗略的工作(见下文)。

我将上下文菜单设置为ContextMenuStrip并链接了一个ItemClick事件。我无法找到将“r”变量传递给StartTimer方法的方法,因此我必须将其设置为全局变量,我知道这并不是正确的C#方式。我确实尝试让EventHandler运行带有int参数的自定义方法,但它出现“Method Name Expected”错误。

正如我所提到的,我的代码确实有用,但我希望得到更多的建议。

private void dataGridView1_MouseClick(object sender, MouseEventArgs e) 
{ 
    if (e.Button == MouseButtons.Right) 
    { 
     int r = dataGridView1.HitTest(e.X, e.Y).RowIndex + 1; 

     ContextMenuStrip m = new ContextMenuStrip(); 

     globals.timer = r; 

     m.Items.Add("Start"); 
     m.Items.Add("Stop"); 
     m.ItemClicked += new ToolStripItemClickedEventHandler(m_ItemClicked); 

     m.Show(dataGridView1, new Point(e.X, e.Y)); 
    } 
} 

void m_ItemClicked(object sender, ToolStripItemClickedEventArgs e) 
{ 
    switch (e.ClickedItem.Text) 
    { 
     case "Start": 
      startTimer(globals.timer); 
      break; 
     case "Stop": 
      stopTimer(globals.timer); 
      break; 
     default: 
      break; 
    } 
} 

private void startTimer(int t) 
{ 
    // code here to start timer t 
} 

private void stopTimer(int t) 
{ 
    // code here to stop timer t 
} 

static class globals 
{ 
    public static int timer = 0; 
} 
+0

'Item.Click + =(sender,e)=> this.StartTimer(r);'背后的想法是您使用lambda函数而不是方法。在lambda函数中,你可以捕获像'r'这样的局部变量,并且可以访问它们,然后lambda调用,所以你不需要全局变量。或者,您可以将'r'保存在ContextMenuStrip属性标记中,并将其用于eventHandler – Nikolay 2012-03-21 06:05:19

+0

好的,再次感谢Nikolay。我之前没有遇到过标签或Lambda,因此会进行一些调查并给出结果。 – Jayie 2012-03-21 10:06:29