C# 使用Caliburn Micro从DataGridComboxColumn捕获TextChanged事件
我在将组合框的C# 使用Caliburn Micro从DataGridComboxColumn捕获TextChanged事件,c#,wpf,events,caliburn.micro,C#,Wpf,Events,Caliburn.micro,我在将组合框的部分文本框的TextChanged事件传递到关联的视图模型时遇到问题 正如所料: 在TextChanged上,调用代码隐藏中的OnTextChanged()方法 在KeyUp上,调用视图模型中的OnKeyUp()方法 然而: 在TextChanged上,不调用视图模型中的OnTextChanged()方法 为什么不调用它?我如何修复它 <UserControl x:Class="AutoComplete.Views.ShellView" xmlns=
部分文本框的TextChanged
事件传递到关联的视图模型时遇到问题
正如所料:
在TextChanged
上,调用代码隐藏中的OnTextChanged()
方法
在KeyUp
上,调用视图模型中的OnKeyUp()
方法
然而:
在TextChanged
上,不调用视图模型中的OnTextChanged()
方法
为什么不调用它?我如何修复它
<UserControl x:Class="AutoComplete.Views.ShellView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:cal="http://www.caliburnproject.org"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300"
>
<UserControl.Resources>
<FrameworkElement x:Key="ProxyElement" DataContext="{Binding}"/>
</UserControl.Resources>
<Grid>
<ContentControl Visibility="Collapsed" Content="{StaticResource ProxyElement}"/>
<DataGrid ItemsSource="{Binding Rows}" AutoGenerateColumns="False" CanUserAddRows="True" CanUserDeleteRows="True">
<DataGrid.Columns>
<DataGridComboBoxColumn Header="Code">
<DataGridComboBoxColumn.EditingElementStyle>
<Style TargetType="ComboBox">
<EventSetter Event="TextBoxBase.TextChanged" Handler="OnTextChanged"/>
<Setter Property="cal:Action.TargetWithoutContext" Value="{Binding DataContext, Source={StaticResource ProxyElement}}"/>
<Setter Property="cal:Message.Attach" Value="[Event TextBoxBase.TextChanged] = [Action OnTextChanged($source, $dataContext)]; [Event KeyUp] = [Action OnKeyUp()]"/>
<Setter Property="IsEditable" Value="True"/>
<Setter Property="ItemsSource" Value="{Binding DataContext.Suggestions, Source={StaticResource ProxyElement}}"/>
</Style>
</DataGridComboBoxColumn.EditingElementStyle>
</DataGridComboBoxColumn>
</DataGrid.Columns>
</DataGrid>
</Grid>
</UserControl>
这不起作用,因为Caliburn Micro默认情况下对消息使用事件触发器
类。附加
。根据EventTrigger
使用反射查找使用EventName
属性的事件,该属性失败,因为ComboBox
未公开名为TextBoxBase.TextChanged的事件。它也不会公开TextChanged
事件,应该捕获的是ComboBox
的TextBox
组件中冒出的TextChanged
上述职位还提供了一个适应性强的解决方案。首先,创建一个新的RoutedEventTrigger
类:
public class RoutedEventTrigger : EventTriggerBase<DependencyObject>
{
public RoutedEvent RoutedEvent { get; set; }
protected override void OnAttached()
{
var element = (AssociatedObject as Behavior as IAttachedObject)?.AssociatedObject as UIElement
?? AssociatedObject as UIElement;
element?.AddHandler(RoutedEvent, new RoutedEventHandler(OnRoutedEvent));
}
void OnRoutedEvent(object sender, RoutedEventArgs args)
{
OnEvent(args);
}
protected override string GetEventName()
{
return RoutedEvent.Name;
}
}
完成此设置后,可以使用冒泡路由事件
public class Bootstrapper : BootstrapperBase
{
public Bootstrapper()
{
Initialize();
}
private RoutedEventTrigger CreateRoutedEventTrigger(DependencyObject target, string routedEvent)
{
var routedEvents = EventManager.GetRoutedEvents().ToDictionary(r => $"{r.OwnerType.Name}.{r.Name}");
if (routedEvents.ContainsKey(routedEvent))
{
var trigger = new RoutedEventTrigger
{
RoutedEvent = routedEvents[routedEvent]
};
trigger.Attach(target);
return trigger;
}
return null;
}
protected override void OnStartup(object sender, StartupEventArgs args)
{
var baseCreateTrigger = Parser.CreateTrigger;
Parser.CreateTrigger = (target, triggerText) =>
{
var baseTrigger = baseCreateTrigger(target, triggerText);
var baseEventTrigger = baseTrigger as EventTrigger;
return CreateRoutedEventTrigger(target, baseEventTrigger?.EventName ?? "") ?? baseTrigger;
};
...
}
...
}