[英]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
元素之后,才能附加事件处理程序。 您可以通过处理ListView
的ItemContainerGenerator
的StatusChanged
事件来实现。
请参考以下示例代码。 它应该给你的想法。
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.