3

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

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

  1. OnNavigatedTo/From
  2. 负载

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

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

编辑

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

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

当人们说我现在也有点困惑

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

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

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

4

2 回答 2

2

正如 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 所说,如果需要,请使用代码隐藏!

于 2013-02-18T19:34:19.280 回答
0

1)不幸的是,我没有找到好的例子,所以你自己一个人。

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

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

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

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

于 2013-04-02T14:58:40.507 回答