Reputation: 145
I hope somebody can help me out here. Simplified the code for posting.
We have a main window (MvvmTestView) with a menu, and a 2nd window (SettingsView) which holds several tabs. I can open the SettingsView window alright. I can even select which Tab to open by setting this in the code.
How can I get back the correct value with the command parameter from the XAML code so that the correct tab opens?
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();
}
}
}
Upvotes: 0
Views: 1795
Reputation: 35646
I suggest to avoid creating multiple command classes like SettingsViewCommand : ICommand
. Instead use some general-purpose command class (e.g. RelayCommand
from MvvmFoundation NuGet package)
assuming you added MvvmFoundation to your project, refactor MvvmTestViewModel class like this:
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 from a view is passed to SettingsWindow
method in a viewModel and used to change selected index
Upvotes: 1