【问题标题】:Simple Event Handling in MVVMMVVM 中的简单事件处理
【发布时间】:2010-12-27 22:11:45
【问题描述】:

只是想知道人们对如何以最轻量级的方式从 View 上的控件中最好地处理 ViewModel 中的事件有什么想法。

例子:

<MediaElement
     MediaOpened={Binding SomeEventHandler} />

在这种情况下,我们希望在 ViewModel 中处理 MediaOpened 事件。如果没有像 Prism 这样的框架,如何将其绑定到 ViewModel?

【问题讨论】:

    标签: wpf xaml mvvm binding


    【解决方案1】:

    小型和开源的ImpromptuInterface.MVVM 框架有一个event binding syntax 并在.net 4.0 中使用dlr。尽管此示例需要对 ImpromptuViewModel 进行子类化。 event binding property 对该特定视图模型类型没有任何依赖关系,并且所涉及的 eventbinding provider 是公共的。

     <Window x:Class="MyProject.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:MVVM="clr-namespace:ImpromptuInterface.MVVM;assembly=ImpromptuInterface.MVVM" Title="MainWindow" Height="600" Width="800">
    
      <MediaElement MVVM:Event.Bind="{Binding Events.MediaOpened.To[MediaElement_MediaOpened]}"  />
    

    ...

    public class MyViewModel{
    
        public dynamic Events
        {
            get { return new EventBinder(this); }
        }
    
        public void MediaElement_MediaOpened(MediaElement sender,   RoutedEventArgs e){
             ...
        }
    }
    

    【讨论】:

      【解决方案2】:

      看看 Marlon Grech 的 Attached Command Behaviors。它使将事件绑定到 ViewModel 命令变得容易

      【讨论】:

        【解决方案3】:

        Commanding - 你的 'SomeEventHandler' 需要是一个实现ICommand 的类...网上有大量的文献...

        另外 - 我会考虑获得一个免费的、轻量级的“迷你”MVVM 框架,例如 MvvmFoundation,它提供了 RelayCommand 来实现这个目的(没有学习 PRISM 的复杂性/开销)

        编辑:

        查看this 博客以将命令附加到任何事件...正如我所提到的,它非常强大,但我想如果这是你想要的,与某些东西相比,你确实需要做出判断就像附加一个老式的事件,并在你的代码中使用一个超薄的事件处理程序,它只是调用你的 ViewModel 上的一些方法,比如:

        public void SomeEventHandler(object sender, SomeEventArgs e)
        {
            MyViewModel vm = (MyViewModel)this.DataContext;
            vm.HandleLoadEvent( );
        }
        

        务实 vs 最佳实践...我会留给你;)

        【讨论】:

        • 我不认为我可以在这种情况下使用 ICommand ...感谢您提供的信息...那么这是一个重复的问题。
        • 好的...我刚刚尝试使用 ICommand,我正在使用 MVVMFoundation,所以它是 RelayCommand 类型。但是,我收到一个构建错误“Binding Path=MediaOpenedCommand, Mode=OneTime}' is not a valid event handler method name ...”我只是设置错了吗?
        • 抱歉,是的...您需要将 RelayCommand 实例绑定到 Command,并通过 CommandBindings 或 InputBindings 将其绑定回 UI...我强烈建议您阅读一些内容- 从事件切换到命令是人们使用 WPF 持续关注的“陡峭学习曲线”之一 - 但是当你摸索它时它是如此强大!
        • 当您在...按钮、超链接等控件上具有“命令”属性时,我会得到命令绑定。我找不到任何示例或解释关于在控件上创建命令属性的示例或解释可以处理类似上面例子的事情。我知道我需要将 RelayCommand 绑定到“命令”......但是如何在 MediaElement 之类的东西上创建一个命令,该命令可以在源加载时执行我的 ICommand(相当于当 MediaOpened 事件触发时)。
        【解决方案4】:

        MediaOpened 是一个事件,不支持命令绑定。

        为了绑定到事件,可以使用辅助对象,该对象附加到事件并执行命令。

        要绑定到视图模型,请添加一个实现 ICommand 的属性。此 MSDN 杂志文章中的图 3 显示了 RelayCommand,它是 ICommand 的一个有用实现。 RelayCommand 使用委托初始化以连接到您的视图模型。

        http://msdn.microsoft.com/en-us/magazine/dd419663.aspx

        【讨论】:

        • 我遇到了命令绑定问题,并且我已经阅读了 Josh Smith 关于 MVVM 的文章,但我遇到的问题是“绑定到可以使用辅助对象的事件附加到事件并执行命令”。您所说的辅助对象是指附加行为吗?
        • 是的,行为是进行绑定的好方法。 IanR 提供的链接看起来不错。
        猜你喜欢
        • 1970-01-01
        • 2010-11-03
        • 1970-01-01
        • 2010-12-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-05-06
        相关资源
        最近更新 更多