[英]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.