我想添加一个交互触发器,如下面的 xaml 示例所示:
<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>
我尝试了这个工作代码(直到添加 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);
但是我无法将交互代码绑定到组合框:
//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);
整个方法 这是理解代码部分如何使用的整个方法:
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;
}
这段代码实际上运行良好,我只是想知道如何以编程方式重现 xaml 代码。
您可以推迟创建触发器并将其放入例如
Loaded
的事件处理程序中。
将此添加到创建
DataTemplate
的方法中:
combobox.AddHandler(ComboBox.LoadedEvent, new RoutedEventHandler(Cmb_Loaded));
.
因此您可以在事件处理程序中附加触发器,您可以在其中访问
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);
}
}