簡體   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