【问题标题】:MVVM How to get away from Code Behind EventsMVVM 如何摆脱事件背后的代码
【发布时间】:2013-02-03 06:19:47
【问题描述】:

在查看了一些 MVVM 工具包(MVVM Light、SimpleMVVM)之后,共同主题似乎尝试使用尽可能多的可混合事件而不是使用代码隐藏。

我不确定如何进行所有活动。例如,在执行 windows phone 7 时会绑定 2 个事件。

  1. OnNavigatedTo/From
  2. 加载中

有没有人有关于如何在 MVVM 中执行此操作的示例?我正在使用 SimpleMVVM,但我希望这些示例可能是相似的,也许 MVVM 轻量级工具包,甚至只是展示这点的一般 MVVM 教程可能会有所帮助。

我只找到了显示如何像按钮单击一样的操作。

编辑

我有点困惑何时使用事件背后的代码或使用混合事件来命令。

例如,在 MVVM Light 教程中,他们使用 MVVM 进行导航,但为什么这比使用代码隐藏事件更好?

现在别人说的时候我也有点糊涂了

代码隐藏并不邪恶;它是业务逻辑和代码隐藏的混合体 这是有问题的。让您的 UI 在代码隐藏中处理 UI 任务。

好吧,在 MVVM 轻量级示例中,当列表或其他任何内容(忘记)正在加载“加载标志出现”时,他们在其中一个示例中有“忙”。这一切都是在 ViewModel 中完成的,而不是代码隐藏事件。

所以这对我来说似乎有点矛盾(也许我错过了一些东西)。让我感到困惑的是,如果 ViewModel 对加载一无所知,你怎么知道加载何时开始或完成?

【问题讨论】:

  • EventToCommand 怎么样? Blend SDK 和 MVVM Light 都提供了这个实现。
  • 你在想这个,但仍然不知道如何使用它。我也在读这篇文章。 blog.tonysneed.com/2011/07/22/…
  • 您可以将 System.Windows.Interactivity 与 Windows-phone-7 一起使用吗?
  • 代码隐藏并不邪恶;它的业务逻辑和代码隐藏的混合是有问题的。让您的 UI 在代码隐藏中处理 UI 任务。你的视图模型不应该知道你什么时候导航,或者你的 UI 元素什么时候加载。
  • 您能否更详细地解释一下“视图模型不应该真正知道您何时导航”。我认为人们确实在 MVVM 中导航。我知道代码隐藏并不邪恶,但似乎第一选择是不使用它,因为它使测试变得更容易。

标签: windows-phone-7 mvvm mvvm-light simple-mvvm


【解决方案1】:

正如 HighCore 评论的那样,使用EventToCommand。它使用起来非常简单,但您首先需要 Blend SDK。

...
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:cmd="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Extras.SL4"
xmlns:im="clr-namespace:Microsoft.Expression.Interactivity.Media;assembly=Microsoft.Expression.Interactions"
xmlns:ic="clr-namespace:Microsoft.Expression.Interactivity.Core;assembly=Microsoft.Expression.Interactions"
...
<i:Interaction.Triggers>
    <i:EventTrigger EventName="Loaded">
            <cmd:EventToCommand Command="{Binding GetTweetsCommand}" CommandParameter="Twitter" />
        </i:EventTrigger>
</i:Interaction.Triggers>

另外,关于代码隐藏的一般要点:在代码隐藏中拥有与 UI 相关的功能并不是世界上最糟糕的事情!它与您的 ViewModel 是分开的,并且位于合乎逻辑的位置。但是,我发现行为更容易测试。例如,使用继承自 TargetedTriggerAction 的类允许情节提要由属性更改和控件控制:

public class ImageAnimationTrigger : TargetedTriggerAction<Storyboard>
{
    protected override void Invoke(object parameter)
    {
        if (Target == null)
            return;

        if (parameter is DependencyPropertyChangedEventArgs)
        {
            DependencyPropertyChangedEventArgs args = (DependencyPropertyChangedEventArgs)parameter;

            if ((bool)args.NewValue)
                Target.Begin();
            else
                Target.Stop();
        }
        else if (parameter is RoutedEventArgs)
        {
            RoutedEventArgs args = (RoutedEventArgs)parameter;

            if (!(args.OriginalSource as Button).IsEnabled)
                Target.Begin();
            else
                Target.Stop();
        }
    }
}

我将此行为与PropertyChangedTrigger 一起使用,如下所示:

<i:Interaction.Triggers>
    <ic:PropertyChangedTrigger Binding="{Binding Loading}">
        <behav:ImageAnimationTrigger TargetName="animStoryboard" />
    </ic:PropertyChangedTrigger>
</i:Interaction.Triggers>

正如 Laurent Bugnion 所说,如果需要,请使用代码隐藏!

【讨论】:

  • 我会尝试一下,看看它是如何工作的。我喜欢混合,所以这不是问题!是否有任何指南可以使用 vs eventToCommands 背后的代码。就像我收集的一样,似乎最好做 eventToCommands 但我只看到点击完成。加载后,我可以看到它所连接的代码,不确定“CommandParameter="Twitter"”
  • 与我交谈过的大多数开发人员都表示,只要遵循模式,就应该如何设置事情没有快速而硬性的规则。我对行为的使用取决于个人喜好。抱歉,调用的命令不清楚。我正在使用 MVVM Light 提供的RelayCommand&lt;T&gt; 类,它实现了 ICommand 接口。该命令指向一个名为 GetTweets 的方法,将字符串作为参数来查询 Twitter 的搜索 API。 “Twitter”只是我指定的一个查询。
  • 如果有帮助,可以在here找到完整代码。这只是我在工作高峰期所做的一点小事。
  • 它不为我编译 "名称 "BooleanToVisibilityConverter" 不存在于命名空间 "clr-namespace:SilverTweetMVVM.Converters"., "找不到所有类型所需的 'async' 修饰符。您的目标是错误的框架版本,还是缺少对程序集的引用?"
  • 嗯,这很奇怪。抱歉,我今天会调查一下。
【解决方案2】:

1) 不幸的是,我没有找到好的例子,所以你只能靠自己了。

2) 如果您将代码隐藏保留为空白(通过使用命令而不是单击按钮),则您只能将代码集中在 ViewModel 中。我可以看到两点好处:

a) 如果您将一个 ViewModel 用于不同的视图(并且在多个视图中有一些通用命令),

b) 如果您使用 ViewModel 的一些私有变量/方法,而这些私有变量/方法在 View 中不可用。

3) 您可以使用 RaisePropertyChanged 加载(重新加载)数据,在 ViewModel 构造函数中加载数据以避免使用 OnNavigatedTo 或其他东西。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-02
    • 1970-01-01
    • 2012-03-02
    • 2012-10-08
    • 2016-10-23
    • 1970-01-01
    相关资源
    最近更新 更多