簡體   English   中英

如何將WPF CommandParameter帶到MVVM中的ViewModel?

[英]How to take a WPF CommandParameter to the ViewModel in MVVM?

我希望有人可以在這里幫助我。 簡化了發布代碼。

我們有一個帶有菜單的主窗口(MvvmTestView),還有一個包含多個選項卡的第二個窗口(SettingsView)。 我可以打開SettingsView窗口。 我什至可以通過在代碼中進行設置來選擇要打開的標簽頁。

如何從XAML代碼中使用命令參數獲取正確的值,以便打開正確的選項卡?

MvvmTestView.xaml:

<Window x:Class="MvvmTest.Views.MvvmTestView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:vm="clr-namespace:MvvmTest.ViewModels"
    WindowStartupLocation="CenterScreen"
    Title="MvvmTestView" 
    Height="500" 
    Width="500">

    <Window.DataContext>
        <vm:MvvmTestViewModel/>
    </Window.DataContext>
    <Grid>
        <DockPanel>
            <Menu>
                <MenuItem Header="Menu">
                    <MenuItem 
                        Header="Tab01" 
                        Command="{Binding SettingsViewCommand}"
                        CommandParameter="0"/>
                    <MenuItem
                        Header="Tab02"
                        Command="{Binding SettingsViewCommand}"
                        CommandParameter="1"/>
                </MenuItem>
            </Menu>
        </DockPanel>
        <DockPanel>
            <Label Content="MainView" HorizontalAlignment="Center" VerticalAlignment="Center"/>
        </DockPanel>
    </Grid>
</Window>

SettingView.xaml

<Window x:Class="MvvmTest.Views.SettingsView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:tabData="clr-namespace:MvvmTest.Views"
    xmlns:vm="clr-namespace:MvvmTest.ViewModels"
    WindowStartupLocation="CenterScreen"
    Title="SettingsView" 
    Height="400"
    Width="400">

    <Window.DataContext>
        <vm:MvvmTestViewModel/>
    </Window.DataContext>
    <Grid>
        <TabControl
            SelectedIndex="{Binding SettingsSelectedIndex, Mode=TwoWay}">
            <tabData:Tab01View/> 
            <tabData:Tab02View/>
        </TabControl>
    </Grid>
</Window>

SettingsViewModel.cs

using System.ComponentModel;

namespace MvvmTest.ViewModels
{
    public class SettingsViewModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        private void OnPropertyChanged(string property)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property));
        }

        private int _settingsSelectedIndex;
        public int SettingsSelectedIndex
        {
            get
            {
                return _settingsSelectedIndex;
            }
            set
            {
                _settingsSelectedIndex = value;
                OnPropertyChanged("SettingsSelectedIndex");
            }
        }
    }
}

MvvmTestViewModel.cs

using MvvmTest.Commands;
using MvvmTest.Views;
using System.ComponentModel;
using System.Windows.Input;

namespace MvvmTest.ViewModels
{
    internal class MvvmTestViewModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        private void OnPropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

        private SettingsViewModel SettingsViewModel;

        public MvvmTestViewModel()
        {
            SettingsViewModel = new SettingsViewModel();
            SettingsViewCommand = new SettingsViewCommand(this);
        }

        public ICommand SettingsViewCommand
        {
            get;
            private set;
        }

        public void SettingsWindow()
        {
            SetIndex();
            SettingsView settingsView = new SettingsView()
            {
                DataContext = SettingsViewModel
            };
            settingsView.ShowDialog();
        }

        public int SetIndex()
        {
            SettingsViewModel.SettingsSelectedIndex = 1;
            return SettingsViewModel.SettingsSelectedIndex;
        }
    }
}

SettingsViewCommand.cs

using MvvmTest.ViewModels;
using System;
using System.Windows.Input;

namespace MvvmTest.Commands
{
    internal class SettingsViewCommand : ICommand
    {
        private MvvmTestViewModel settingsViewModel;

        public SettingsViewCommand(MvvmTestViewModel settingsViewModel)
        {
            this.settingsViewModel = settingsViewModel;
        }

        public event EventHandler CanExecuteChanged
        {
            add
            {
                CommandManager.RequerySuggested += value;
            }
            remove
            {
                CommandManager.RequerySuggested -= value;
            }
        }

        public bool CanExecute(object parameter)
        {
            return true;
        }

        public void Execute(object parameter)
        {
            settingsViewModel.SettingsWindow();
        }
    }
}

我建議避免創建多個命令類,例如SettingsViewCommand : ICommand 代替使用一些通用的命令類(例如RelayCommandMvvmFoundation NuGet包)

假設您將MvvmFoundation添加到您的項目中,則重構MvvmTestViewModel類,如下所示:

internal class MvvmTestViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    private void OnPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

    private SettingsViewModel SettingsViewModel;

    public MvvmTestViewModel()
    {
        SettingsViewModel = new SettingsViewModel();
        SettingsViewCommand = new RelayCommand<int>(SettingsWindow);
    }

    public ICommand SettingsViewCommand
    {
        get;
        private set;
    }

    public void SettingsWindow(int index)
    {
        SettingsViewModel.SettingsSelectedIndex = index;
        SettingsView settingsView = new SettingsView()
        {
            DataContext = SettingsViewModel
        };
        settingsView.ShowDialog();
    }
}

視圖中的CommandParameter傳遞給viewModel中的SettingsWindow方法,並用於更改所選索引

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM