使用Microsoft.Toolkit.Mvvm和Microsoft.Xaml.Behaviors.Wpf将事件参数传递到命令

3
我尝试使用Microsoft.Toolkit.Mvvm为this sample(仅包含简单的分页部分)实现MVVM模式,但很遗憾,我失败了:(因为我对WPF和MVVM都很菜:))
主要问题是如何使用InvokeCommandAction(Microsoft.Xaml.Behaviors.Wpf)将事件的参数传递给命令? 我认为文档和维基百科都很有限...... 在这种情况下,我更改了MainWindow.xaml中的代码。
...
        <ui:Frame x:Name="ContentFrame" Navigated="ContentFrame_Navigated" />
    </ui:NavigationView>

目标收件人:
            ...
<ui:Frame x:Name="ContentFrame" DataContext="{Binding ContentFrameVM}">
            <i:Interaction.Triggers>
                <!--  Events  -->
                <i:EventTrigger EventName="Navigated">
                    <i:InvokeCommandAction Command="{Binding ContentFrame_NavigatedCommand}" PassEventArgsToCommand="True"/>
                </i:EventTrigger>
            </i:Interaction.Triggers>
        </ui:Frame>

将与此事件相关的代码从MainWindow.xaml.cs移动:
        private void ContentFrame_Navigated(object sender, NavigationEventArgs e)
    {
        if (e.SourcePageType() == typeof(SettingsPage))
        {
            NavView.SelectedItem = NavView.SettingsItem;
        }
        else
        {
            NavView.SelectedItem = NavView.MenuItems.OfType<NavigationViewItem>().FirstOrDefault(x => GetPageType(x) == e.SourcePageType());
        }
    }

将其更改为 MainWindowViewModel.cs:
   class MainWindowViewModel : ObservableObject
  {
  public IRelayCommand ContentFrame_NavigatedCommand { get; }
  private NavigationView _navigationViewVM;
    public NavigationView NavigationViewVM
    {
        get => _navigationViewVM;
        set => SetProperty(ref _navigationViewVM, value);
    }

    private ModernWpf.Controls.Frame _contentFrameVM;
    public ModernWpf.Controls.Frame ContentFrameVM
    {
        get => _contentFrameVM;
        set => SetProperty(ref _contentFrameVM, value);
    }

    public MainWindowViewModel()
    {
        ContentFrame_NavigatedCommand = new RelayCommand<object>(ContentFrame_Navigated, (o) => { return true; });
    }
    ...

    private void ContentFrame_Navigated(object o)
    {
        NavigationEventArgs e = o as NavigationEventArgs;
        if (e.SourcePageType() == typeof(Views.Pages.SettingsPage))
        {
            NavigationViewVM.SelectedItem = NavigationViewVM.SettingsItem;
        }
        else
        {
            NavigationViewVM.SelectedItem = NavigationViewVM.MenuItems.OfType<NavigationViewItem>().FirstOrDefault(x => GetPageType(x) == e.SourcePageType());
        }
    }

或者尝试这个:
public MainWindowViewModel()
    {
        ContentFrame_NavigatedCommand = new RelayCommand<NavigationEventArgs>(ContentFrame_Navigated);
    }
...
private void ContentFrame_Navigated(NavigationEventArgs e)
    {
        ...
    }

在调试模式下,“ContentFrame_Navigated”根本不触发,“ContentFrame_NavigatedCommand”只在启动时触发一次(此时“NavigationViewVM”为空!)
我是否忽略了一个明显的问题?同时,这可能是一个重复的问题,对此我很抱歉,但我尝试了几天阅读所有类似的问题和参考资料!

你的命令位于 MainWindowViewModel 中,但你正在将 DataContext 设置为 ContentFrameVM?绑定引擎正在寻找 ContentFrameVM 上名为 ContentFrame_Navigated 的命令。 - Jesse Good
1个回答

4

感谢Jesse的评论... 我编辑了代码的那一部分,但主要问题是ItemInvoked事件根本没有实现!然而,我决定改为实现SelectionChanged事件: MainWindow.xaml :

<ui:NavigationView>
<i:Interaction.Triggers>
            <i:EventTrigger EventName="SelectionChanged" SourceObject="{Binding ElementName=NavView}">
                <i:InvokeCommandAction Command="{Binding NavVM_SelectionChangedCommand}" PassEventArgsToCommand="True"/>
            </i:EventTrigger>
  </i:Interaction.Triggers>
   ...

在 MainWindowViewModel.cs 中:

 private void NavVM_SelectionChanged(NavigationViewSelectionChangedEventArgs args)
    {
        if (args.IsSettingsSelected)
        {
            Navigate(typeof(Views.Pages.SettingsPage));
        }
        else
        {
            var selectedItem = (NavigationViewItem)args.SelectedItem;
            Navigate(selectedItem);
        }
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接