使用Caliburn Micro从DataGridComboBoxColumn捕获TextChanged事件

时间:2015-12-16 16:36:54

标签: c# wpf events caliburn.micro

我在将TextChanged的{​​{1}}部分的TextBox事件传递给关联的视图模型时遇到问题。

正如所料:

  1. ComboBox上调用后面代码中的TextChanged方法。
  2. OnTextChanged()上调用视图模型中的KeyUp方法。
  3. 然而:

    1. OnKeyUp()上,未调用视图模型中的TextChanged方法。
    2. 为什么不调用它,我该如何解决?

      OnTextChanged()

1 个答案:

答案 0 :(得分:1)

这不起作用,因为Caliburn Micro默认使用EventTriggerMessage.Attach。根据{{​​3}} EventTrigger使用反射来查找事件使用EventName属性失败,因为ComboBox没有公开名为TextBoxBase.TextChanged的事件。它也没有公开TextChanged事件,它是TextChangedTextBox组成的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。