2

I would like to add an interaction trigger as in the xaml example below:

<ComboBox ...>
    <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>

I tried this working code (until add Interaction.Trigger):

//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);

But I cannot bind the Interaction code to the ComboBox:

//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(combobox); <= this raises an error
triggers.Add(eventTrigger);

Whole Method Here is the whole method to understand how the parts of code are used:

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));

    //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);

    //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);
            
    //Set to DataTemplate
    var datatemplate = new DataTemplate();
    datatemplate.VisualTree = combobox;

    //Set to DataGridTemplateColumn
    column.CellTemplate = datatemplate;

    return column;
}

This code works well actually, I'm just wondering how to reproduce the xaml code programmatically.

2
  • Do you want to do this process behind the code? If you want to do it code-behind, what's the point of it? Commented May 8, 2023 at 21:00
  • It's a part of a behavior to manage DataGrid columns from the view model see: stackoverflow.com/questions/36737997/… Commented May 9, 2023 at 8:30

1 Answer 1

0

You can defer a trigger creation and put it for instance to the event handler for Loaded.

Add this to the method where DataTemplate being created:

combobox.AddHandler(ComboBox.LoadedEvent, new RoutedEventHandler(Cmb_Loaded));.

Triggers thus you can attach in the event handler, where you have access to the ComboBox:

private static void Cmb_Loaded(object sender, RoutedEventArgs e)
{
    if (sender is ComboBox cmb)
    {
        var invokeCommandAction = new InvokeCommandAction { CommandParameter = "{Binding Path=.}" };
        var binding = new Binding { Path = new PropertyPath("DataContext.DropDownCommand"), RelativeSource=new RelativeSource(RelativeSourceMode.FindAncestor, typeof(Window), 1) };
        BindingOperations.SetBinding(invokeCommandAction, InvokeCommandAction.CommandProperty, binding);

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

        TriggerCollection triggers = Interaction.GetTriggers(cmb);
        triggers.Add(eventTrigger);
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

Does this solution work for you?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.