Caliburn Micro"Enter"键事件 [英] Caliburn Micro 'Enter' Key Event

查看:136
本文介绍了Caliburn Micro"Enter"键事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将事件与Caliburn Micro绑定在一起,但是在将正确的消息发送给该方法时遇到了一些问题.我想增加在文本框中更改值后按"Enter"键的功能,它执行与旁边的按钮绑定到的方法相同的方法.但是,无论按下哪个键,我都会遇到以下异常:

I am attempting to bind an event with Caliburn Micro and I am having some issues getting the right messages to the method. I would like to add the ability to press the 'Enter' key after changing the value in a text box and it execute the same method that the button next to is bound to. However, regardless of which key is pressed, I get the following exceptions:

类型为'System.InvalidCastException'的第一次机会异常 发生在MyApp.exe

A first chance exception of type 'System.InvalidCastException' occurred in MyApp.exe

类型的第一次机会异常 mscorlib.dll中发生了'System.Reflection.TargetInvocationException'

A first chance exception of type 'System.Reflection.TargetInvocationException' occurred in mscorlib.dll

类型的第一次机会异常 "System.Reflection.TargetInvocationException"发生在 WindowsBase.dll

A first chance exception of type 'System.Reflection.TargetInvocationException' occurred in WindowsBase.dll

在另一个类似的问题绑定KeyDown事件Silverlight 的建议下,我尝试了使用ActionExecutionContext,但无济于事.

At the suggestion of another, similar question Binding KeyDown Event Silverlight, I've tried using ActionExecutionContext, but to no avail.

这是xaml:

<TextBox Name="Threshold"                     
              Margin="5"
              Grid.Column="1"
              >
     <i:Interaction.Triggers>
         <i:EventTrigger EventName="KeyDown">
             <cal:ActionMessage MethodName="ExecuteFilterView">
                 <cal:Parameter Value="$executionContext"/>
             </cal:ActionMessage>
         </i:EventTrigger>
     </i:Interaction.Triggers>
</TextBox>

方法:

 public void ExecuteFilterView(ActionExecutionContext context)
    {
        //Do stuff...
    }

我知道我可能会为自己省去一些麻烦,只需在后面的代码中执行一个标准的事件处理程序即可,但是此应用程序是MVVM中的一项练习,正在学习利用Caliburn.Micro,因此,我坚持这样做特殊的方法工作.

I understand that I could probably save myself some headaches and simply do a standard event handler in the code behind, but this app is an exercise in MVVM and learning to utilize Caliburn.Micro, so I would like to stick with making this particular approach work.

我只是想从事件中发送错误的信息吗?我的xaml是否没有正确编码才能得到我想要的东西?还是我完全错过了其他东西?

Am I just trying to send the wrong information from the event? Is my xaml not coded properly to get what I want? Or I have missed something else entirely?

推荐答案

只需一起进行测试,这两项对我都有效:

Just threw a test together, both of these work for me:

使用完整语法:

    <TextBox Name="Threshold"                     
          Margin="5"
          Grid.Column="1">
        <i:Interaction.Triggers>
            <i:EventTrigger EventName="KeyDown">
                <cal:ActionMessage MethodName="ExecuteFilterView">
                    <cal:Parameter Value="$executionContext"/>
                </cal:ActionMessage>
            </i:EventTrigger>
        </i:Interaction.Triggers>
    </TextBox>

使用CM语法(建议使用此语法,因为它更具可读性)

Using CM syntax (prefer this as it's way more readable)

    <TextBox Name="Threshold"                     
          Margin="5"
          Grid.Column="1"
          cal:Message.Attach="[Event KeyDown] = [Action ExecuteFilterView($executionContext)]" />            

这是测试虚拟机:

public class MainWindowViewModel
{
    public void ExecuteFilterView(ActionExecutionContext context)
    { 
        // This method is hit and the context is present and correct
    }
}

您可以发布完整的代码-您确定框架设置正确吗? (您是否遵循了入门示例?

Can you post your full code - are you sure you have the framework setup correctly? (have you followed the getting started example?

http://caliburnmicro. codeplex.com/wikipage?title=Basic%20Configuration%2c%20Actions%20and%20Conventions&referringTitle=文档

好的,在您澄清之后,我可以为您提供一些有关如何执行此操作的示例-我会告诉您我的个人偏好和原因,但是请选择最适合您的

Ok after your clarification I can give you some examples of how to do this - I'll tell you my personal preference and why, but choose the one that fits you best

  1. 使用ActionExecutionContext并投射eventargs:
  1. Using ActionExecutionContext and casting the eventargs:

    cal:Message.Attach="[Event KeyDown] = [Action ExecuteFilterView($executionContext)]"

    public void ExecuteFilterView(ActionExecutionContext context)
    {
        var keyArgs = context.EventArgs as KeyEventArgs;

        if (keyArgs != null && keyArgs.Key == Key.Enter)
        {
            // Do Stuff
        }
    }

  1. 直接使用EventArgs

    cal:Message.Attach="[Event KeyDown] = [Action ExecuteFilterView($eventArgs)]"

    public void ExecuteFilterView(KeyEventArgs keyArgs)
    {
        if (keyArgs.Key == Key.Enter)
        {
            // Do Stuff
        }
    }

  1. 我个人的最爱,创建了自己的SpecialValues词典条目:
  1. My personal fave, creating your own SpecialValues dictionary entry:

在您的Bootstrapper.Configure方法中...

MessageBinder.SpecialValues.Add("$pressedkey", (context) =>
{
    // NOTE: IMPORTANT - you MUST add the dictionary key as lowercase as CM
    // does a ToLower on the param string you add in the action message, in fact ideally
    // all your param messages should be lowercase just in case. I don't really like this
    // behaviour but that's how it is!
    var keyArgs = context.EventArgs as KeyEventArgs;

    if (keyArgs != null)
        return keyArgs.Key;

    return null;
});

您的操作:

cal:Message.Attach="[Event KeyDown] = [Action ExecuteFilterView($pressedKey)]"

和代码:

public void ExecuteFilterView(Key key)
{
    if (key == Key.Enter)
    {
        // Do Stuff
    }
}

这是我最喜欢的原因吗?这意味着您的VM只是接收到您想要的值(大多数情况下,您不需要关心很多其他参数),并且您不需要知道如何或不应该强制转换eventargs-您可以进行操作的价值.显然使用最适合您的东西

The reason this is my favourite? It means that your VM just receives the value you want (most of the time you don't care about a lot of the other parameters) and you don't need to know how to or bother to cast the eventargs - you can just operate on the value. Obviously use whatever is best for you

还值得注意的是,如果您具有子类KeyEventArgs的其他类型的控件,则它们将对它们起作用.如果他们不继承KeyEventArgs的子类,但是它们仍然返回类型Key的值,那么它也仍然可以工作,因为如果第一个失败,则可以向委托添加另一个强制类型转换:

It's also worth noting, that if you have other types of controls that subclass KeyEventArgs this will work for them. If they don't subclass KeyEventArgs but they still return a value of type Key this will still work too as you can just add another cast to the delegate if the first one fails:

例如

MessageBinder.SpecialValues.Add("$pressedkey", (context) =>
{
    var keyArgs = context.EventArgs as KeyEventArgs;

    if (keyArgs != null)
        return keyArgs.Key;

    // Ok so it wasn't KeyEventArgs... check for some other type - maybe a 3rd party implementation
    var thirdPartyKeyArgs = context.EventArgs as ThirdPartyKeyArgs;

    if (thirdPartyKeyArgs != null)
        return thirdPartyKeyArgs.KeyProperty;

    return null;
});

这篇关于Caliburn Micro"Enter"键事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆