在MVVM中使用命令

时间:2011-02-23 10:15:46

标签: wpf mvvm mvvm-light

我一直在使用ApuntasNotas中非常好的示例代码来详细了解如何有效地使用MVVM Light Toolkit

在代码中,在一个实例中,作者似乎只是使用后面的代码来设置DataContext以处理click事件,我觉得这很令人困惑。

在XAML中,ContextMenu EditNote_Click中的MenuItem的cm事件处理程序在代码隐藏中处理:

    <Window x:Class="ApuntaNotas.MainWindow" Icon="Icons/app_48.ico"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="Apunta Notas"
            Height="480"
            x:Name="Ventana"
            Width="640"
            Background="Beige"
            DataContext="{Binding Main, Source={StaticResource Locator}}">
.
.
.
<ScrollViewer VerticalScrollBarVisibility="Auto">
            <ItemsControl Background="Beige" Padding="15" Tag="Hello" x:Name="IC"
                      ItemsSource="{Binding Notes}">
                <ItemsControl.LayoutTransform>
                    <ScaleTransform ScaleX="{Binding Value, ElementName=zoomSlider}" ScaleY="{Binding Value, ElementName=zoomSlider}" />
                </ItemsControl.LayoutTransform>
                <ItemsControl.ContextMenu>
                    <ContextMenu Name="icCM">
                        <MenuItem Header="{Binding Source={StaticResource LocStrings}, Path=DeleteAllNotes}" Command="{Binding DeleteAllNotesCommand}" />
                    </ContextMenu>
                </ItemsControl.ContextMenu>
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <Grid>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="auto" />
                                <ColumnDefinition Width="*" />
                            </Grid.ColumnDefinitions>
                            <Grid.ContextMenu>
                                <ContextMenu Name="cm">
                                    <MenuItem Header="{Binding Source={StaticResource LocStrings}, Path=Edit}" Click="EditNote_Click"/>
                                    <MenuItem Header="{Binding Source={StaticResource LocStrings}, Path=Delete}" Click="DeleteNote_Click" />
                                    <Separator />
                                    <ComboBox Loaded="CmbNoteCategory_Loaded" SelectionChanged="CmbNoteCategory_SelectionChanged">
                                        <ComboBox.ItemTemplate>
                                            <DataTemplate>
                                                <TextBlock Text="{Binding Name}" />
                                            </DataTemplate>
                                        </ComboBox.ItemTemplate>
                                    </ComboBox>
                                </ContextMenu>
.
.
.

在代码隐藏中,EditNote_Click处理程序定义如下:

private void EditNote_Click(object sender, RoutedEventArgs e)
        {
            var menuItem = e.Source as MenuItem;
            if (menuItem != null)
                ViewModel.EditNoteCommand.Execute(menuItem.DataContext as Model.Note);
        }

EditNoteCommand具有以下签名:

public RelayCommand<Note> EditNoteCommand { get; private set; }

我的问题是,作者为什么不将EditNoteCommand命令(已编写和可用)链接到XAML中Command的{​​{1}}属性?< / p>

例如,我试图替换以下编译但生成异常的内容(如下所示)。我怀疑我的方法是合理的,但我遗漏了一些关于将DataContext或其他东西传递给命令代码的东西。我将DataContext绑定重置为MenuItem以便于命令绑定:

Main

此尝试在<MenuItem Header="{Binding Source={StaticResource LocStrings}, Path=Edit}" DataContext="{Binding Main, Source={StaticResource Locator}}" Command="{Binding EditNoteCommand}"/> 中引用other生成以下例外 - EditNote调用的方法:

EditNote:

EditNoteCommand

例外:

private void EditNote(Note other)
        {
            ActualNote = other;
            SelectedCategory = other.Category;
        }

1 个答案:

答案 0 :(得分:3)

如果不需要使用代码隐藏,你肯定是在正确的轨道上 - 所以在你的MVVM中继续关注那个主体并且你会做得很好。

我想你会发现这里的作者正在使用代码隐藏来解决使命令参数正确的问题。 对于编辑注释命令 - 正在编辑的注释的视图模型是必需参数。他们在这里的代码中做了什么 -

menuItem.DataContext as Model.Note

您遇到的问题是访问单击的菜单项以及同一命令中的“主”视图模型。

如果您要将EditNoteCommand移动到NotesViewModel(或Notes中的任何类),您可以将命令保存在XAML中,例如:

<MenuItem Header="{Binding Source={StaticResource LocStrings}, Path=Edit}" Command="{Binding EditNoteCommand}" />

HTH, 斯科特