【问题标题】:Galasoft RelayCommand not firingGalasoft RelayCommand 未触发
【发布时间】:2011-03-10 09:00:28
【问题描述】:

我正在使用 MVVM Light 框架来构建一个 SL4 应用程序。我的简单应用程序主要由一个主视图(shellView)组成,它分为多个用户控件。它们只是 UI 的方便分离,因此它们没有自己的 ViewModel。

ShellView 包含一个 Keypad(自定义用户控件),其中包含多个 KeypadButtons(自定义用户控件)。

我很确定(因为我已经检查过)DataContext 设置正确并且被层次结构中的所有用户控件使用。 (ShellView的Datacontext是ShellViewModel,Keypad的DataContext是ShellViewModel等)。

在 ShellViewModel 中,我有一个名为“ProcessKey”的 ICommand (RelayCommand)。

在键盘控件中,我有类似的东西:

<controls:KeypadButton x:Name="testBtn" Text="Hello">
        <i:Interaction.Triggers>
            <i:EventTrigger EventName="Click">
                <GalaSoft_MvvmLight_Command:EventToCommand Command="{Binding PressStandardKeyCommand}" />
            </i:EventTrigger>
        </i:Interaction.Triggers>
</controls:KeypadButton>

KeypadButton 基本上是一个包含按钮的网格。捕获 MouseLeftButtonUp 事件并触发自定义“Click”事件。让我给你看一些代码来轻松解释我在做什么:

public partial class KeypadButton : UserControl
{
    public delegate void KeypadButtonClickHandler(object sender, RoutedEventArgs e);
    public event KeypadButtonClickHandler Click;

public KeypadButton()
{
        // Required to initialize variables
    InitializeComponent();
}

    private void innerButton_Click(object sender, MouseButtonEventArgs e)
    {
        if (Click != null)
            Click(sender, new KeypadButtonEventArgs());
    }
}

public class KeypadButtonEventArgs : RoutedEventArgs
{
    public string test { get; set; }
}

现在,如果我为 innerButton_Click 的主体设置断点,我可以看到 Click 被正确捕获,并且它包含指向 RelayCommand 的点。但是,什么也没有发生:“单击(发件人,新的 KeypadButtonEventArgs());”被执行,但仅此而已。

为什么会这样?不应该执行 RelayCommand 中定义的目标函数吗?也许是与范围相关的问题?

提前致谢, 干杯, 詹卢卡。

【问题讨论】:

    标签: silverlight mvvm mvvm-light relaycommand


    【解决方案1】:

    正如其他 cmets 所指出的,这可能与 Click 事件不是 RoutedEvent 有关。

    作为一个快速的技巧,您也许可以在您的UserControl 上使用MouseLeftButtonDown 而不是Click 事件。

    <!-- Kinda Hacky Click Interception -->
    <controls:KeypadButton x:Name="testBtn" Text="Hello">
            <i:Interaction.Triggers>
                <i:EventTrigger EventName="MouseLeftButtonDown">
                    <GalaSoft_MvvmLight_Command:EventToCommand Command="{Binding PressStandardKeyCommand}" />
                </i:EventTrigger>
            </i:Interaction.Triggers>
    </controls:KeypadButton>
    

    您可以考虑的另一个选项是从Button 继承而不是UserControl。 Silverlight Show 有一个可能与此相关的article about inheriting from a TextBox

    【讨论】:

    • +1,尤其是关于继承你需要的东西,而不是从 Control/UserControl 一路向下 - 除非绝对需要。
    • @Alex:谢谢,但我相信我们在这里忽略了重点。另外,我已经尝试过 MouseLeftButtonUp (应该是相同的),但它没有用。 KeypadButton 的事件已生成,我可以通过代码以编程方式订阅它。问题似乎是 EventTrigger 无法捕获生成的事件。我在这里发布了这个问题,以了解是否需要以某种特定方式实现 silvelright 用户控件中的自定义事件才能在 XAML 和 EventToCommand 中工作。
    【解决方案2】:

    路由事件应该这样定义(see documentation):

    public static readonly RoutedEvent TapEvent = EventManager.RegisterRoutedEvent(
        "Tap", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(MyButtonSimple));
    
    // Provide CLR accessors for the event
    public event RoutedEventHandler Tap
    {
            add { AddHandler(TapEvent, value); } 
            remove { RemoveHandler(TapEvent, value); }
    }
    

    【讨论】:

    • 正如我在帖子中所说,我使用的是 SL4。据我所知,那里没有 EventManager。我错了吗?
    • 我尝试将我的自定义事件处理程序声明为 RoutedEventHandler,但我仍然遇到同样的问题。我可以看到 Click 事件中有一个 EventTriggerBase 实例,但是当它实际上应该被调用时,什么也没有发生。任何帮助将非常感激!谢谢大家!
    • 抱歉,不知道您使用的是 SL(下次需要更好地阅读)。根据这篇文章 (silverlightshow.net/items/Routed-Events-in-Silverlight.aspx),SL 不支持自定义路由事件。
    • 为什么不在控件上实现ICommand呢?那么问题就解决了。
    猜你喜欢
    • 1970-01-01
    • 2022-01-06
    • 2016-02-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-27
    • 1970-01-01
    相关资源
    最近更新 更多