"MainView"및 일부 중첩 된 뷰가있는 Catel 응용 프로그램이 있습니다. 중첩 된 뷰는 ListView
이고 일부 항목은 ContextMenu
이고 일부는 MenuItems
입니다.Catel - CommandParameter를 전달하지 않는 CommandManager
MainView의 ViewModel에서 전달 된 매개 변수로 무언가를 수행 할 TaskCommand<object>
을 만들었습니다. 이 전달 된 매개 변수는 ListView
의 현재 SelectedItem
이어야합니다. 이 명령은 ICommandManager
에 전역 적으로 등록됩니다.
MenuItem
의 명령어를 ICommandManager
에서 바인딩하면 전달 된 매개 변수는 항상 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
을 클릭하고 행동을 설명 할 경우이 메서드가 호출 될 것이라고 가정한다.
OnExecute
메서드에 (바인딩 된) 매개 변수를 전달하기위한 적절한 해결책이나 해결 방법이 있습니까? 명령이
의 MenuItem 헤더 = "마 물건" CommandParameter는 = "{DataContext.SelectedItem 바인딩, ElementName을 = UserControl을 XAML에서 바인딩 전에 바인딩 CommandParameter
를 미리 설정
ContextMenu와 UserControl이 다른 요소 트리에 있기 때문에 ContextMenu의 MenuItem에서 ElementName = UserControl에 바인딩 할 수 없습니다. Command = "{Binding}"을 사용하여 바인딩 한 MenuItem의 DataContext는 ContextMenu를 열 때 클릭하는 항목입니다. 이것은 현재 선택된 항목과 반드시 같을 필요는 없습니다. – mm8