以编程方式从mainwindow在用户控件的datagridtemplatecolumn中添加按钮单击事件

以编程方式从mainwindow在用户控件的datagridtemplatecolumn中添加按钮单击事件

问题描述:

我有一个MainWindow。它有一个堆栈面板myStack和其他一些东西。 在stackPanel中,以编程方式添加了一个用户控件(TaskGrid(_TG))。 在这个UserControl中,有一个DataGrid(dgEmployee),它有4个模板列。最后一列包含一个按钮。以编程方式从mainwindow在用户控件的datagridtemplatecolumn中添加按钮单击事件

我想从主窗口构造函数中分配按钮单击事件,并在这里处理事件。

这里是代码:

MainWindow.xaml

<Grid Grid.Row="2"> 
    <StackPanel Name="myStack"/> 
</Grid> 

MainWindow.xaml.cs

public MainWindow() 
{ 
    InitializeComponent(); 
    _TG = new TaskGrid(); 
    _TD = new _1.TaskDetails(); 
    _TM = new _1.TaskMaster(); 
    myStack.Children.Add(_TG); 
    _AUC = ActiveUserControl.Grid; 

    foreach (object child in myStack.Children) 
    { 
     string childname = ""; 
     if (child is FrameworkElement) 
     { 
      childname = (child as FrameworkElement).Name; 
      if (childname == "TaskGrid") 
      { 
       Grid dg = ((Grid)((UserControl)child).Content); 
       foreach (var item in dg.Children) 
       { 
        DataGridColumn b = ((DataGrid)item).Columns[3] as DataGridColumn; 

       } 
      } 
     } 
    } 
} 

而且在TaskGrid.xaml,则此处仅给出模板列

<DataGridTemplateColumn Width="30"> 
    <DataGridTemplateColumn.CellTemplate> 
     <ItemContainerTemplate> 
      <Button Name="btnMaster" Background="Transparent"> 
       <Button.Template> 
        <ControlTemplate> 
         <Image Source="ArrowRight.png"/> 
        </ControlTemplate> 
       </Button.Template> 
      </Button> 
     </ItemContainerTemplate> 
    </DataGridTemplateColumn.CellTemplate> 
</DataGridTemplateColumn> 

我必须分配click事件像

button.click += new RoutedEvent(button_click); 

后来在

等到UserControl已经加载了MainWindow.xaml.cs使用button_click事件。然后,您可以使用以下帮助器方法获取对DataGrid的引用,该方法在可视树中以递归方式搜索特定类型的元素。

private static T GetChildOfType<T>(DependencyObject depObj) where T : DependencyObject 
{ 
    if (depObj == null) 
     return null; 

    for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++) 
    { 
     var child = VisualTreeHelper.GetChild(depObj, i); 

     var result = (child as T) ?? GetChildOfType<T>(child); 
     if (result != null) return result; 
    } 
    return null; 
} 

用同样的方法,你可以得到一个特定的单元格的引用:

public static DataGridCell GetCell(DataGrid dataGrid, DataGridRow rowContainer, int column) 
{ 
    if (rowContainer != null) 
    { 
     System.Windows.Controls.Primitives.DataGridCellsPresenter presenter = 
      GetChildOfType<System.Windows.Controls.Primitives.DataGridCellsPresenter>(rowContainer); 
     if (presenter != null) 
      return presenter.ItemContainerGenerator.ContainerFromIndex(column) as DataGridCell; 
    } 
    return null; 
} 

请参考下面的博客文章,了解更多有关这个:https://blog.magnusmontin.net/2013/11/08/how-to-programmatically-select-and-focus-a-row-or-cell-in-a-datagrid-in-wpf/

下面是一个完整的例子为你。请注意,DataGrid可能包含多行,并且某些行可能已被虚拟化。您可以在上面的链接中找到关于此的更多信息。

public MainWindow() 
{ 
    InitializeComponent(); 

    _TG = new TaskGrid(); 
    _TD = new _1.TaskDetails(); 
    _TM = new _1.TaskMaster(); 
    myStack.Children.Add(_TG); 
    _AUC = ActiveUserControl.Grid; 

    _TG.Loaded += (s, e) => 
    { 
     DataGrid dataGrid = GetChildOfType<DataGrid>(_TG); 
     if (dataGrid != null) 
     { 
      foreach (var item in dataGrid.Items) 
      { 
       DataGridRow dgr = dataGrid.ItemContainerGenerator.ContainerFromItem(item) as DataGridRow; 
       if (dgr != null) 
       { 
        DataGridCell cell = GetCell(dataGrid, dgr, 3); //<-- column index 
        if (cell != null) 
        { 
         Button button = GetChildOfType<Button>(cell); 
         if (button != null) 
         { 
          button.Click += new RoutedEvent(button_click); 
         } 
        } 
       } 
      } 
     } 
    }; 
} 
+0

后来我从usercontrol捕获了主窗口实例作为父窗口。所以我试图从主窗口处理网格中的按钮单击事件的方式变得没有必要。所以我无法测试你的代码。但从逻辑上来看似乎是对的,所以我把它作为一个正确的答案。谢谢你的帮助。 –