菜单上的 WPF selectedItem 或在 viewmodel 中获取命令参数
WPF selectedItem on Menu or get commandparameter in viewmodel
我正在寻找几个小时来解决一个简单的问题。我想在我的 menuItems 上使用 "SelectedItem",但在使用 Whosebug 数小时后,我发现这是不可能的。我发现了很多关于 "CommandParameter" 的信息,但我不明白它是如何工作的。
这就是我想要做的:我有一个带有 "background1, background2,..." 的菜单。如果您 select 菜单中的背景,我想将那个 select 编辑的背景设置为背景。
这是一个学校项目,所以我们必须使用 MVVM,并且不允许代码隐藏。
我如何 "use" 我的 ViewModel 中的命令参数?
这是我的 mainWindow.xaml:
<Toolbar>
<Menu>
<MenuItem Header="Background" ItemsSource="{Binding Backgrounds}">
<MenuItem.ItemTemplate>
<DataTemplate>
<MenuItem Header="{Binding Name}" Command="{Binding ChangeBackgroundCommand}" CommandParameter="{Binding Name}"/>
</DataTemplate>
</MenuItem.ItemTemplate>
</MenuItem>
</Menu>
</Toolbar>
这是我的 mainWindowViewModel 的一部分:
public MainWindowViewModel()
{
//load data
BackgroundDataService bds = new BackgroundDataService();
Backgrounds = bds.GetBackgrounds();
//connect command
WijzigBackgroundCommand = new BaseCommand(WijzigBackground);
}
private void ChangeBackground()
{
//I want here the name of the selected menuItem (by parameter?)
}
}
我们使用一个 baseCommand class(我不想改变这个 class 因为我认为它是标准的):
class BaseCommand : ICommand
{
Action actie;
public BaseCommand(Action Actie)
{
actie = Actie;
}
public event EventHandler CanExecuteChanged;
public bool CanExecute(object parameter)
{
return true;
}
public void Execute(object parameter)
{
actie.Invoke();
}
}
我经常使用 Whosebug :-) 这是我的第一次 post/question,我希望它是清楚的
试试这个:
class BaseCommand<T> : ICommand
{
private readonly Action<T> _executeMethod = null;
private readonly Func<T, bool> _canExecuteMethod = null;
public BaseCommand(Action<T> executeMethod)
: this(executeMethod, null)
{
}
public BaseCommand(Action<T> executeMethod, Func<T, bool> canExecuteMethod)
{
_executeMethod = executeMethod;
_canExecuteMethod = canExecuteMethod;
}
public bool CanExecute(T parameter)
{
if (_canExecuteMethod != null)
{
return _canExecuteMethod(parameter);
}
return true;
}
public void Execute(T parameter)
{
if (_executeMethod != null)
{
_executeMethod(parameter);
}
}
public event EventHandler CanExecuteChanged;
bool ICommand.CanExecute(object parameter)
{
if (parameter == null &&
typeof(T).IsValueType)
{
return (_canExecuteMethod == null);
}
return CanExecute((T)parameter);
}
void ICommand.Execute(object parameter)
{
Execute((T)parameter);
}
}
这样使用:
public MainWindowViewModel()
{
// ...
// connect command
WijzigBackgroundCommand = new BaseCommand<YourBackgroundClass>(
(commandParam) => WijzigBackground(commandParam),
(commandParam) => CanWijzigBackground(commandParam));
}
private void WijzigBackground(YourBackgroundClass param)
{
// Use 'param'
}
private bool CanWijzigBackground(YourBackgroundClass param)
{
// Use 'param'
}
我正在寻找几个小时来解决一个简单的问题。我想在我的 menuItems 上使用 "SelectedItem",但在使用 Whosebug 数小时后,我发现这是不可能的。我发现了很多关于 "CommandParameter" 的信息,但我不明白它是如何工作的。 这就是我想要做的:我有一个带有 "background1, background2,..." 的菜单。如果您 select 菜单中的背景,我想将那个 select 编辑的背景设置为背景。
这是一个学校项目,所以我们必须使用 MVVM,并且不允许代码隐藏。 我如何 "use" 我的 ViewModel 中的命令参数?
这是我的 mainWindow.xaml:
<Toolbar>
<Menu>
<MenuItem Header="Background" ItemsSource="{Binding Backgrounds}">
<MenuItem.ItemTemplate>
<DataTemplate>
<MenuItem Header="{Binding Name}" Command="{Binding ChangeBackgroundCommand}" CommandParameter="{Binding Name}"/>
</DataTemplate>
</MenuItem.ItemTemplate>
</MenuItem>
</Menu>
</Toolbar>
这是我的 mainWindowViewModel 的一部分:
public MainWindowViewModel()
{
//load data
BackgroundDataService bds = new BackgroundDataService();
Backgrounds = bds.GetBackgrounds();
//connect command
WijzigBackgroundCommand = new BaseCommand(WijzigBackground);
}
private void ChangeBackground()
{
//I want here the name of the selected menuItem (by parameter?)
}
}
我们使用一个 baseCommand class(我不想改变这个 class 因为我认为它是标准的):
class BaseCommand : ICommand
{
Action actie;
public BaseCommand(Action Actie)
{
actie = Actie;
}
public event EventHandler CanExecuteChanged;
public bool CanExecute(object parameter)
{
return true;
}
public void Execute(object parameter)
{
actie.Invoke();
}
}
我经常使用 Whosebug :-) 这是我的第一次 post/question,我希望它是清楚的
试试这个:
class BaseCommand<T> : ICommand
{
private readonly Action<T> _executeMethod = null;
private readonly Func<T, bool> _canExecuteMethod = null;
public BaseCommand(Action<T> executeMethod)
: this(executeMethod, null)
{
}
public BaseCommand(Action<T> executeMethod, Func<T, bool> canExecuteMethod)
{
_executeMethod = executeMethod;
_canExecuteMethod = canExecuteMethod;
}
public bool CanExecute(T parameter)
{
if (_canExecuteMethod != null)
{
return _canExecuteMethod(parameter);
}
return true;
}
public void Execute(T parameter)
{
if (_executeMethod != null)
{
_executeMethod(parameter);
}
}
public event EventHandler CanExecuteChanged;
bool ICommand.CanExecute(object parameter)
{
if (parameter == null &&
typeof(T).IsValueType)
{
return (_canExecuteMethod == null);
}
return CanExecute((T)parameter);
}
void ICommand.Execute(object parameter)
{
Execute((T)parameter);
}
}
这样使用:
public MainWindowViewModel()
{
// ...
// connect command
WijzigBackgroundCommand = new BaseCommand<YourBackgroundClass>(
(commandParam) => WijzigBackground(commandParam),
(commandParam) => CanWijzigBackground(commandParam));
}
private void WijzigBackground(YourBackgroundClass param)
{
// Use 'param'
}
private bool CanWijzigBackground(YourBackgroundClass param)
{
// Use 'param'
}