gpt4 book ai didi

c# - Catel - CommandManager 未传递 CommandParameter

转载 作者:行者123 更新时间:2023-12-03 11:03:29 27 4
gpt4 key购买 nike

我有一个带有“MainView”和一些嵌套 View 的 Catel 应用程序。
嵌套 View 具有 ListView一些项目有 ContextMenu与一些 MenuItems .

在 MainView 的 ViewModel 中,我创建了一个 TaskCommand<object>这将对传递的参数做一些事情。这个传递的参数应该是当前的SelectedItemListView .此命令正在全局注册到 ICommandManager .

如果我点击 MenuItem使用来自 ICommandManager 的绑定(bind)命令,传递的参数将始终为 null .

这里是相关代码:

NestedView.xaml:

<catel:UserControl
x:Name="UserControl"
x:Class="My.NameSpace.Views.View"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:catel="http://catel.codeplex.com">

...
<ListView ItemsSource="{Binding Items}"
BorderThickness="0"
SelectedItem="{Binding SelectedItem}"
HorizontalContentAlignment="Stretch">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock VerticalAlignment="Center"
Margin="2.5"
Text="{Binding Description}">
<TextBlock.ContextMenu>
<ContextMenu>
<MenuItem Header="Do Stuff"
Command="{catel:CommandManagerBinding DoStuffCommand}"
CommandParameter="{Binding DataContext.SelectedItem, ElementName=UserControl}" />
...
</ContextMenu>
</TextBlock.ContextMenu>
</TextBlock>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ListView>
...
</catel:UserControl>

MainViewModel.cs:
public class MainViewModel : ViewModelBase {
...

public ICommand DoStuffCommand { get; }

public MainViewModel(ICommandManager commandManager, IUIVisualizerService uiVisualizerService, IMessageService messageService)
{
...

DoStuffCommand = new TaskCommand<object>(OnDoStuffCommandExecute);

commandManager.CreateCommand(nameof(DoStuffCommand));
commandManager.RegisterCommand(nameof(DoStuffCommand), DoStuffCommand, this);
}

private async Task OnDoStuffCommandExecute(object parameter)
{
// command needs to be in the MainViewModel because there will be some modification on the MainView based on parameter (adding tabs, etc)
Debugger.Break();
}

...
}

如果您需要更多代码,我也可以发布此代码,但这应该足够了。

我还查看了 Catel 的 CommandManager实现并发现:
    /// <summary>
/// Executes the command.
/// </summary>
/// <param name="commandName">Name of the command.</param>
/// <exception cref="ArgumentException">The <paramref name="commandName"/> is <c>null</c> or whitespace.</exception>
/// <exception cref="InvalidOperationException">The specified command is not created using the <see cref="CreateCommand"/> method.</exception>
public void ExecuteCommand(string commandName)
{
Argument.IsNotNullOrWhitespace("commandName", commandName);

lock (_lockObject)
{
Log.Debug("Executing command '{0}'", commandName);

if (!_commands.ContainsKey(commandName))
{
throw Log.ErrorAndCreateException<InvalidOperationException>("Command '{0}' is not yet created using the CreateCommand method", commandName);
}

_commands[commandName].Execute(null);
}
}

我假设如果我单击 MenuItem 将调用此方法并会解释这种行为。

是否有任何适当的解决方案/解决方法可以将(绑定(bind))参数传递给我的 OnExecute方法?

提前致谢

最佳答案

  • 设置CommandParameter xaml 中的命令绑定(bind)之前的绑定(bind)

    MenuItem 标题="做的东西"
    CommandParameter="{绑定(bind) DataContext.SelectedItem, ElementName=UserControl}"
    Command="{catel:CommandManagerBinding DoStuffCommand}"
  • 请记住,菜单项中的绑定(bind)上下文是 项目 ,而不是 查看模型 .如果要绑定(bind)到 View 模型,则需要为根网格提供名称并像这样绑定(bind):
    CommandParameter="{Binding DataContext.SelectedItem, ElementName=rootGrid}"

  • 请注意,使用 UserControl无法正常工作,因为 VM 设置在内部网格内(请参阅文档了解原因)。所以要么使用 UserControl.ViewModelSomeInnerControl.DataContext

    关于c# - Catel - CommandManager 未传递 CommandParameter,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42811516/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com