我在将TextChanged
的{{1}}部分的TextBox
事件传递给关联的视图模型时遇到问题。
正如所料:
ComboBox
上调用后面代码中的TextChanged
方法。OnTextChanged()
上调用视图模型中的KeyUp
方法。然而:
OnKeyUp()
上,未调用视图模型中的TextChanged
方法。为什么不调用它,我该如何解决?
OnTextChanged()
答案 0 :(得分:1)
这不起作用,因为Caliburn Micro默认使用EventTrigger
类Message.Attach
。根据{{3}} EventTrigger
使用反射来查找事件使用EventName
属性失败,因为ComboBox
没有公开名为TextBoxBase.TextChanged
的事件。它也没有公开TextChanged
事件,它是TextChanged
从TextBox
组成的ComboBox
冒出的应该被捕获的事件。
上述帖子还提供了一个适应性强的解决方案。首先创建一个新的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;
}
}
然后,如果可能,Caliburn Micro配置为使用RoutedEventTrigger而不是EventTrigger:
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;
};
...
}
...
}
在此设置之后,可以使用冒泡RoutedEvents。