WPF Command с несколькими типами целей - PullRequest
7 голосов
/ 11 января 2011

Я немного запутался в командах WPF с разными типами целей.

Так что, если я определю команду

<Window.CommandBindings>
        <CommandBinding Command="Copy"
                        Executed="CopyCmdExecuted"
                        CanExecute="CopyCmdCanExecute"/>

    </Window.CommandBindings>

А теперь я использую его в контекстном меню:

                    <ContextMenu Name="FolderContextMenu">
                        <MenuItem Command="Copy"/>
                        </ContextMenu>

И у меня есть метод для обработки команды:

private void CopyCmdExecuted(object sender, ExecutedRoutedEventArgs e)
{


}

И я использую его в простом старом меню:

    <Menu  Name="editMenu">
        <MenuItem Command="Copy"/>
    </Menu>

У меня нет проблем с пониманием этого. Но я немного запутался в том, что я должен делать, если целевые объекты бывают разных типов.

Допустим, у меня есть папки и пользователи, у каждого из которых есть контекстное меню с командой New (и меню редактирования строки меню, которое также имеет команду New).

Когда выполняется New, независимо от того, является ли она Папкой или Пользователем, выполняется CopyCmdExecuted. Итак, теперь я должен демультиплексировать на цели? Что-то вроде

   private void CopyCmdExecuted(object sender, ExecutedRoutedEventArgs e)
        {
           if(sender is User)
               // Do copy user stuff
           if(sender is Folder)
               // Do copy folder stuff
        }

Если я получаю много типов данных, которые хочу скопировать, это немного раздражает. Я что-то здесь не понимаю?

(Очевидно, я мог бы просто сделать так, чтобы папка и пользователь наследовали от базового класса Copiable с помощью DoCopy, но это все равно кажется неправильным.)

1 Ответ

2 голосов
/ 11 января 2011

Вы можете отправить CommandParameter при вызове Command, чтобы указать, что вы имеете в виду команду, к которой нужно применить.Вот два TextBlock элемента:

<Grid>
    <StackPanel>
        <TextBlock Name="textBlock1" Text="File">
            <TextBlock.ContextMenu>
                <ContextMenu>
                    <MenuItem
                        Command="Copy"
                        CommandParameter="{Binding PlacementTarget, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContextMenu}}}"/>
                </ContextMenu>
            </TextBlock.ContextMenu>
        </TextBlock>
        <TextBlock Name="textBlock2" Text="Folder">
            <TextBlock.ContextMenu>
                <ContextMenu>
                    <MenuItem
                        Command="Copy"
                        CommandParameter="{Binding PlacementTarget, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContextMenu}}}"/>
                </ContextMenu>
            </TextBlock.ContextMenu>
        </TextBlock>
    </StackPanel>
</Grid>

и этот код:

    private void CopyCmdExecuted(object sender, ExecutedRoutedEventArgs e)
    {
        var text = (e.Parameter as TextBlock).Text;
        Debug.WriteLine("Text = " + text);
    }

использует параметр, чтобы выяснить, к какому TextBlock относится контекстное меню.Вы также можете просто использовать строки "File" и "Folder", если это работает для вас.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...