WPF add Interraction trigger programmatically

Yannick Lalbatry 21 Reputation points
2023-05-09T09:33:11.19+00:00

I have a behavior to help to bind a DataGrid Columns collection from the VM. Here below the sample in xaml that I want to achieve:

<DataGridTemplateColumn Width="*" Header="Names">
	<DataGridTemplateColumn.CellTemplate>
    	<DataTemplate>
        	<ComboBox ItemsSource="{Binding DataContext.NamesList, RelativeSource={RelativeSource Findancestor, AncestorType={ x:Type Window}}}"
                      SelectedItem="{Binding Name, UpdateSourceTrigger=PropertyChanged}"
                      Style="{StaticResource DataGridComboBox}"
                      DisplayMemberPath="Name">
            	<i:Interaction.Triggers>
                	<i:EventTrigger EventName="DropDownClosed">
            			<i:InvokeCommandAction Command="{Binding DataContext.DropDownCommand, RelativeSource={RelativeSource Findancestor, AncestorType = { x:Type Window}}}" CommandParameter="{Binding Path=.}" />
            		</i:EventTrigger>
            	</i:Interaction.Triggers>
        		<ComboBox.ItemContainerStyle>
            		<Style TargetType="ComboBoxItem" BasedOn="{StaticResource DataGridComboBoxItemContainerStyle}">
            			<Setter Property="IsEnabled" Value="{Binding IsSelectable}"/>
            		</Style>
            	</ComboBox.ItemContainerStyle>
        	</ComboBox>
    	</DataTemplate>
	</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>

For this I have a Method to return a DataGridTemplateColumn:

private static DataGridTemplateColumn GetComboBoxUniqueColumn(ComboBoxUniqueColumn columnName)	
{
    DataGridTemplateColumn column = new DataGridTemplateColumn();
    column.IsReadOnly = true;
    column.Header = columnName.DisplayColumnName;
    column.Width = columnName.Width;
    column.MinWidth = GetMinWidth(columnName.Width);

    //Binding
    Binding selectedItembinding = new Binding();
    selectedItembinding.Path = new PropertyPath(columnName.SelectedItemPropertyName);
    selectedItembinding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;

    Binding itemsourcebinding = new Binding();
    itemsourcebinding.Path = new PropertyPath(string.Format("DataContext.{0}", columnName.ItemSourcePropertyName));
    itemsourcebinding.RelativeSource = new RelativeSource(RelativeSourceMode.FindAncestor, typeof(Window), 1);

    Binding isselectablebinding = new Binding();
    isselectablebinding.Path = new PropertyPath("IsSelectable");

    //Style
    Style comboBoxStyle = Application.Current.Resources["DataGridComboBox"] as Style;

    Style itemContainerStyle = new Style();
    itemContainerStyle.TargetType = typeof(ComboBoxItem);
    itemContainerStyle.BasedOn = Application.Current.Resources["DataGridComboBoxItemContainerStyle"] as Style;
    itemContainerStyle.Setters.Add(new Setter(ComboBoxItem.IsEnabledProperty, isselectablebinding));

    //Interaction.Triggers
    //InvokeCommandAction invokeCommandAction = new InvokeCommandAction { CommandParameter = "{Binding Path=.}" };
    //Binding binding = new Binding { Path = new PropertyPath("DataContext.DropDownCommand") };
    //BindingOperations.SetBinding(invokeCommandAction, InvokeCommandAction.CommandProperty, binding);

    //Microsoft.Xaml.Behaviors.EventTrigger eventTrigger = new Microsoft.Xaml.Behaviors.EventTrigger { EventName = "DropDownClosed" };
    //eventTrigger.Actions.Add(invokeCommandAction);

    //TriggerCollection triggers = Interaction.GetTriggers(??);
    //triggers.Add(eventTrigger);

    //ComboBox
    FrameworkElementFactory combobox = new FrameworkElementFactory(typeof(ComboBox));
    combobox.SetBinding(ComboBox.SelectedItemProperty, selectedItembinding);
    combobox.SetBinding(ComboBox.ItemsSourceProperty, itemsourcebinding);
    combobox.SetValue(ComboBox.DisplayMemberPathProperty, columnName.DisplayMemberPathName);
    combobox.SetValue(ComboBox.StyleProperty, comboBoxStyle);
    combobox.SetValue(ComboBox.ItemContainerStyleProperty, itemContainerStyle);
            
    //Set to DataTemplate
    var datatemplate = new DataTemplate();
    datatemplate.VisualTree = combobox;

    //Set to DataGridTemplateColumn
    column.CellTemplate = datatemplate;

    return column;
}

This works perfectly but I don't see how to add the Interaction Trigger part in the method.

Thanks

Windows Presentation Foundation
Windows Presentation Foundation
A part of the .NET Framework that provides a unified programming model for building line-of-business desktop applications on Windows.
2,710 questions
{count} votes