2

我尝试使用 MVVM 模式来绑定ItemClickOptionItemClick事件来命令。根据文档https://developer.microsoft.com/en-us/windows/uwp-community-toolkit/api/microsoft_toolkit_uwp_ui_controls_hamburgermenu没有Command我可以绑定的。所以我正在考虑使用https://www.nuget.org/packages/Microsoft.Xaml.Behaviors.Uwp.Managed/包将我的事件触发器附加到命令。

我的 XAML 代码是

<Page
    x:Class="App1.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:i="using:Microsoft.Xaml.Interactivity"
    xmlns:ic="using:Microsoft.Xaml.Interactions.Core"
    xmlns:localModel="using:App1.Models"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:controls="using:Microsoft.Toolkit.Uwp.UI.Controls"
    mc:Ignorable="d">

    <Page.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <localTemplate:TemplatesResourceDictionary/>
            </ResourceDictionary.MergedDictionaries>
            <DataTemplate x:Key="DefaultTemplate" x:DataType="localModel:MenuItem">
                <Grid Width="240" Height="48" Margin="0,0,0,0" HorizontalAlignment="Left">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="48" />
                        <ColumnDefinition />
                    </Grid.ColumnDefinitions>
                    <SymbolIcon Grid.Column="0" Symbol="{x:Bind Icon, Mode=OneWay}" Foreground="White" />
                    <TextBlock Grid.Column="1" Text="{x:Bind Name, Mode=OneWay}" FontSize="16" VerticalAlignment="Center" Foreground="White" />
                </Grid>
            </DataTemplate>
        </ResourceDictionary>
    </Page.Resources>

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <controls:HamburgerMenu x:Name="hamburgerMenuControl"
                                Grid.Row="0"
                                Grid.Column="0"
                                PaneBackground="Black"
                                Foreground="White"
                                DisplayMode="CompactOverlay"
                                ItemsSource="{Binding Path=MainMenuItems}"
                                ItemTemplate="{StaticResource DefaultTemplate}"
                                OptionsItemsSource="{Binding Path=OptionMenuItems}"
                                OptionsItemTemplate="{StaticResource DefaultTemplate}"
                                OptionsItemClick="OnMenuItemClick">
            <i:Interaction.Behaviors>
                <ic:EventTriggerBehavior EventName="ItemClick">
                    <ic:InvokeCommandAction Command="{Binding Path=NavigateCommand}" />
                </ic:EventTriggerBehavior>
            </i:Interaction.Behaviors>
            <Frame x:Name="contentFrame" />
        </controls:HamburgerMenu>
    </Grid>
</Page>

首先,代码在 VS2017 中看起来很有趣,但它不会产生编译错误。 在此处输入图像描述

其次,当我启动代码并单击菜单项时,生成的代码 App.gics 中会引发异常 在此处输入图像描述

并且还有进一步的消息要求我启动另一个调试器。

调试器附加到 App1.exe 但未配置为调试此未处理的异常。要调试此异常,请分离当前调试器。

任何线索,将命令绑定到我的视图模型的正确方法是什么?

4

1 回答 1

2

我没有在 XAML 中看到您Page的 '设置为您的视图模型,所以我想这是在后面的代码中完成的。DataContext

就像 Andrey 提到的那样,您可以在将鼠标悬停在e参数上时看到实际的异常,或者在 Watch 窗口中检查它的值。我的第一个想法是您的视图模型中的命令类型错误,因为您的 XAML 似乎是正确的。传递给您的视图模型的参数不是绑定到您的实际类型HamburgerMenubut ItemClickedEventArgs

这是 的代码DelegateCommand,但是RelayCommand(或您使用的任何ICommand实现)应该是相似的。

public DelegateCommand<ItemClickEventArgs> NavigateCommand { get; }

private void OnMenuItemClicked(ItemClickEventArgs args)
{
    HamburgerMenuPrismItem menuItem = (HamburgerMenuPrismItem)args.ClickedItem;
    _navigationService.Navigate(menuItem.TargetPageToken, null);
}

请注意 HamburgerMenuPrismItem 是我自己的类型,这应该是您绑定到 HamburgerMenu 的类型。

前段时间我创建了一个类似的示例(使用 Prism 作为 MVVM 框架),因此您可以自己在GitHub 上查看源代码。

奖励:如果您自己添加了 Microsoft.Xaml.Behaviors.Uwp.Managed,则不需要它(除非您想指定版本)。您的 HamburgerMenu 需要 Microsoft.Toolkit.Uwp.UI.Controls,它会引入 Microsoft.Toolkit.Uwp.UI.Animations,它本身会引入 Microsoft.Xaml.Behaviors.Uwp.Managed。

于 2017-09-21T06:22:37.067 回答