如何将WPF CommandParameter带入MVVM中的ViewModel?

时间:2017-07-16 21:17:54

标签: c# wpf xaml mvvm data-binding

我希望有人可以帮助我。简化了发布的代码。

我们有一个带有菜单的主窗口(MvvmTestView)和一个包含多个选项卡的第二个窗口(SettingsView)。我可以打开SettingsView窗口。我甚至可以通过在代码中设置它来选择要打开的Tab。

如何使用XAML代码中的命令参数返回正确的值,以便打开正确的选项卡?

MvvmTestView.xaml:

>> bm1 = ('#' in CounterpartyList) | df1['Counterparty'].isin(CounterpartyList)
>> bm2 = ('#' in MaturityList) | df1['Maturity'].isin(MaturityList)
>> df1.loc[bm1 & bm2, 'Match'] = 420
>> df1
   Amount Counterparty  Match  Maturity
0      50         Bank    420         2
1      55       Client    420         3
2      65          GSE      0         2
3      55          PSE      0         2

SettingView.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>

SettingsViewModel.cs

<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>

MvvmTestViewModel.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");
            }
        }
    }
}

SettingsViewCommand.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;
        }
    }
}

1 个答案:

答案 0 :(得分:1)

我建议避免创建多个命令类,如SettingsViewCommand : ICommand。而是使用一些通用命令类(例如来自MvvmFoundation NuGet包的RelayCommand

假设您已将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方法并用于更改所选索引