繁体   English   中英

将事件绑定到使用WPF中的数据模板创建的控件

[英]Binding an event to a control created with a data template in WPF

在我的WPF项目中,我在“代码隐藏”中创建了一个自定义ListView。 此ListView中的一列包含一个按钮,该按钮由我的资源字典中的数据模板定义。

<DataTemplate x:Key="DataTemplate_EditButton">
  <Button Style="{DynamicResource Button_Image}" Width="25" ... />
</DataTemplate>

初始化ListView时,我使用以下代码创建该列:

GridViewColumn buttonColumn = new GridViewColumn();
DataTemplate dt = Application.Current.TryFindResource("DataTemplate_EditButton") as DataTemplate;
buttonColumn.CellTemplate = dt;
...

gridView.Columns.Add(buttonColumn);

现在,我想将事件处理程序绑定到按钮的click事件。 我无法在模板中执行此操作,因为我将需要在Dictionary的类后面创建代码,并且无论如何我都需要ListView-UserControl中的事件处理程序。 当我用数据模板创建列时,当然没有办法访问为每一行创建的按钮。

处理以上述方式创建的按钮的click事件的最佳方法是什么?

提前致谢,
坦率

由于您的模板是在许多控件之间共享的,因此,好的方法可能是使用路由命令。 首先声明一个命令(或使用现有命令之一,例如,来自ApplicationCommands类):

public static class Commands {
    public static RoutedCommand EditRow = new RoutedCommand("Edit", typeof(Commands));
}

在模板中使用以下命令:

<DataTemplate x:Key="DataTemplate_EditButton">
    <Button x:Name="button" Command="{x:Static my:Commands.EditRow}" />
</DataTemplate>

然后绑定到控件中的该命令(在构造函数中):

this.CommandBindings.Add(new CommandBinding(Commands.EditRow, EditButtonClicked));

private void EditButtonClicked(object sender, ExecutedRoutedEventArgs args) 
{
    var button = args.OriginalSource;
    // do what you need here
}

处理以上述方式创建的按钮的click事件的最佳方法是什么?

您需要等到实际创建Button元素之后,才能附加事件处理程序。 您可以通过处理ListViewItemContainerGeneratorStatusChanged事件来实现。

请参考以下示例代码。 它应该给你的想法。

private void ItemContainerGenerator_StatusChanged(object sender, EventArgs e)
{
    ItemContainerGenerator icg = sender as ItemContainerGenerator;
    if (icg.Status == System.Windows.Controls.Primitives.GeneratorStatus.ContainersGenerated)
    {
        foreach (var item in icg.Items)
        {
            var container = icg.ContainerFromItem(item) as ListViewItem;
            Button button = FindVisualChild<Button>(container);
            if (button != null)
            {
                button.Click -= Button_Click;
                button.Click += Button_Click;
            }
        }
    }
}

private void Button_Click(object sender, RoutedEventArgs e)
{
    MessageBox.Show("clicked");
}

private static T FindVisualChild<T>(DependencyObject parent) where T : DependencyObject
{
    for (int childCount = 0; childCount < VisualTreeHelper.GetChildrenCount(parent); childCount++)
    {
        DependencyObject child = VisualTreeHelper.GetChild(parent, childCount);
        if (child != null && child is T)
            return (T)child;
        else
        {
            T childOfChild = FindVisualChild<T>(child);
            if (childOfChild != null)
                return childOfChild;
        }
    }
    return null;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM