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

Adding button click event in datagridtemplatecolumn in user control from mainwindow programmatically

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

我正在尝试从主窗口构造函数分配按钮单击事件并在此处处理该事件。

代码如下:

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>

我必须像

这样分配点击事件
button.click += new RoutedEvent(button_click);

然后在 MainWindow.xaml.cs

中使用 button_click 事件

等待 UserControl 加载完毕。然后,您可以使用以下辅助方法获取对 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;
}

有关这方面的更多信息,请参阅以下博客 post:https://blog.magnusmontin.net/2013/11/08/how-to-programmatically-select-and-focus-a-row-or-cell-in-a-datagrid-in-wpf/

下面是一个完整的例子。请注意,DataGrid 可能包含多行,其中一些行可能已被虚拟化掉。您将在上面的 link 中找到有关此内容的更多信息。

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);
                        }
                    }
                }
            }
        }
    };
}