C# 以编程方式运行WPF事件处理程序

C# 以编程方式运行WPF事件处理程序,c#,wpf,C#,Wpf,对于wpf datagrid,我有以下两个事件: 1-CellEditEnding 2-PreviewKeyDown 当我在datagrid的任何单元格中完成编辑时,首先运行PreviewKeyDown事件,然后运行CellEditEnding。但我需要先运行CellEditEnding,然后再运行PreviewKeyDown。因此,我在CellEditEnding事件中通过编写以下代码以编程方式调用PreviewKeydown事件 private void maingrid_CellEditE

对于wpf datagrid,我有以下两个事件:

1-CellEditEnding

2-PreviewKeyDown

当我在datagrid的任何单元格中完成编辑时,首先运行PreviewKeyDown事件,然后运行CellEditEnding。但我需要先运行CellEditEnding,然后再运行PreviewKeyDown。因此,我在CellEditEnding事件中通过编写以下代码以编程方式调用PreviewKeydown事件

private void maingrid_CellEditEnding(object sender, DataGridCellEditEndingEventArgs e)
{
    TextBox t = e.EditingElement as TextBox;
    DataGridColumn dgc = e.Column;
    if ((string)dgc.Header == "Product Id")
    {
        if (vm_order.PopulateProductRow(maingrid.SelectedIndex, Convert.ToInt32(t.Text)) == false)
        {
            MessageBox.Show("Product does not exists           ", "Message", MessageBoxButton.OK);
        }
    }

    **maingrid.PreviewKeyDown += new maingrid_PreviewKeyDown(maingrid_PreviewKeyDown);**
}
请查看我以编程方式调用PreviewKeyDownEvent的最后一行代码,它给出了错误

我已经看到了wpf datagrid的mouse_up事件的一个示例,它工作得非常好。以下是参考代码:

public EventsSample()
{
    InitializeComponent();
    pnlMainGrid.MouseUp += new MouseButtonEventHandler(pnlMainGrid_MouseUp);
}

private void pnlMainGrid_MouseUp(object sender, MouseButtonEventArgs e)
{
    MessageBox.Show("You clicked me at " + e.GetPosition(this).ToString());
}

那么,为什么我不能将其用于PreviewKeyDown事件呢?

有几个问题。首先,第行出现语法错误
maingrid.PreviewKeyDown+=新的maingrid\u PreviewKeyDown(maingrid\u PreviewKeyDown)
这是不正确的
maingrid\u PreviewKeyDown
是方法的名称,不能“新建”方法。这就是导致编译器错误的原因。订阅活动的正确方式是:
mainGrid.PreviewKeyDown+=新的KeyEventHandler(mainGrid\u PreviewKeyDown)

查看您自己的MouseUp事件代码。此表单与您自己的代码订阅鼠标事件的方式一致。但是请注意,这是一种非常古老的语法。因为C#2或者可能是C#3,我们有一个更简单的形式。你可以写:
mainGrid.PreviewKeyDown+=mainGrid\u PreviewKeyDown

pnlMainGrid.MouseUp+=pnlMainGrid\u MouseUp

然而,你有一个更大的问题。我将使用正确的语法复制您的代码,然后尝试解释更大的问题是什么:

01  private void maingrid_CellEditEnding(object sender, DataGridCellEditEndingEventArgs e)
02  {
03      TextBox t = e.EditingElement as TextBox;
04      DataGridColumn dgc = e.Column;
05      if ((string)dgc.Header == "Product Id")
06      {
07          if (vm_order.PopulateProductRow(maingrid.SelectedIndex, Convert.ToInt32(t.Text)) == false)
08          {
09              MessageBox.Show("Product does not exists           ", "Message", MessageBoxButton.OK);
10          }
11      }
12
13      mainGrid.PreviewKeyDown += new KeyEventHandler(mainGrid_PreviewKeyDown);
14  }
第13行:
mainGrid.PreviewKeyDown+=新的KeyEventHandler(mainGrid\u PreviewKeyDown)
您没有调用事件处理程序。您仅订阅该活动。换句话说,您是在告诉系统下次将引发事件
PreviewKeyDown
,您希望调用方法
mainGrid\u PreviewKeyDown
。这意味着第一次调用
maingrid\u CellEditEnding
时,您正在订阅
PreviewKeyDown
。下次调用
maingrid\u CellEditEnding
时,您将再次订阅
PreviewKeyDown
。此时,您有两个事件处理程序(恰好是相同的方法)与事件
PreviewKeyDown
关联。下次引发
PreviewKeyDown
时,将为同一事件调用两次
mainGrid\u PreviewKeyDown
。在调用
CellEditEnding
10次之后,
maingrid\u CellEditEnding
将被调用10次。该活动
PreviewKeyDown
也将订阅10次。此时,下次引发
PreviewKeyDown
时,其事件处理程序–即方法
mainGrid\u PreviewKeyDown
将为同一事件调用10次

要了解这一点,我建议您通过以下方式实施
mainGrid\u PreviewKeyDown

void mainGrid_PreviewKeyDown(object sender, KeyEventArgs e)
{
    Debug.WriteLine("mainGrid_PreviewKeyDown was called");
}
运行应用程序并密切关注Visual Studio调试输出。
注意:要显示调试输出窗口,请转到[菜单/debug/Windows/output]

要解决此问题,您有几个选项:

选项1
只有在方法
mainGrid\u PreviewKeyDown
中未使用参数
object sender
KeyEventArgs e
中包含的信息时,这才有效。如果是这种情况,请执行以下操作:

  • 不再订阅
    PreviewKeyDown
    事件
  • 重写
    maingrid\u CellEditEnding
    ,以便在方法结束时执行通常在
    maingrid\u PreviewKeyDown
    中执行的操作。这样,您将按照需要的顺序执行操作
选项2
如果您确实需要参数
对象发送器
或'KeyEventArgs e'中包含的信息

  • 订阅
    CellEditEnding
    PreviewKeyDown
    事件
  • 调用
    PreviewKeyDown
    的处理程序时,暂时不要执行任何操作,只在某些字段中存储稍后需要的
    KeyEventArgs
    中的信息
  • 调用
    CellEditEnding
    的处理程序时,请执行处理
    CellEditEnding
    的任何操作。完成此操作后,使用先前存储的有关
    KeyEventArgs
    的信息来执行有关PreviewKeyDown事件的任何操作
选项3

查找其他具有您喜欢的顺序的要订阅的活动

有几个问题。首先,第行出现语法错误
maingrid.PreviewKeyDown+=新的maingrid\u PreviewKeyDown(maingrid\u PreviewKeyDown)
这是不正确的
maingrid\u PreviewKeyDown
是方法的名称,不能“新建”方法。这就是导致编译器错误的原因。订阅活动的正确方式是:
mainGrid.PreviewKeyDown+=新的KeyEventHandler(mainGrid\u PreviewKeyDown)

查看您自己的MouseUp事件代码。此表单与您自己的代码订阅鼠标事件的方式一致。但是请注意,这是一种非常古老的语法。因为C#2或者可能是C#3,我们有一个更简单的形式。你可以写:
mainGrid.PreviewKeyDown+=mainGrid\u PreviewKeyDown

pnlMainGrid.MouseUp+=pnlMainGrid\u MouseUp

然而,你有一个更大的问题。我将使用正确的语法复制您的代码,然后尝试解释更大的问题是什么:

01  private void maingrid_CellEditEnding(object sender, DataGridCellEditEndingEventArgs e)
02  {
03      TextBox t = e.EditingElement as TextBox;
04      DataGridColumn dgc = e.Column;
05      if ((string)dgc.Header == "Product Id")
06      {
07          if (vm_order.PopulateProductRow(maingrid.SelectedIndex, Convert.ToInt32(t.Text)) == false)
08          {
09              MessageBox.Show("Product does not exists           ", "Message", MessageBoxButton.OK);
10          }
11      }
12
13      mainGrid.PreviewKeyDown += new KeyEventHandler(mainGrid_PreviewKeyDown);
14  }
第13行:
mainGrid.PreviewKeyDown+=新的KeyEventHandler(mainGrid\u PreviewKeyDown)
您没有调用事件处理程序。你只是订阅