Команды и меню - PullRequest
       36

Команды и меню

0 голосов
/ 27 января 2012

У меня есть собственный UserControl, который содержит несколько границ, содержащих элементы управления TextBlock.Свойство Text для TextBlocks установлено на данные из моего объекта ViewModel.

Я добавил пару контекстных меню к ресурсам UserControl:

<UserControl.Resources>
    <ContextMenu x:Key="ContextMenu">
        <MenuItem Header="Copy Plate"   Command="cs:CarSystemCommands.CopyPlateCommand" />
        <MenuItem Header="Search Plate" Command="cs:CarSystemCommands.SearchPlateCommand" />
    </ContextMenu>
    <ContextMenu x:Key="TextBoxContextMenu">
        <MenuItem Header="_Copy"        Command="Copy" />
        <MenuItem Header="Copy Plate"   Command="cs:CarSystemCommands.CopyPlateCommand" />
        <MenuItem Header="Search Plate" Command="cs:CarSystemCommands.SearchPlateCommand" />
    </ContextMenu>
</UserControl.Resources>

Я добавил ссылки наконтекстные меню для моих TextBlocks.Вот пример:

<Border Background="#FFFFFF78" 
        BorderBrush="Black" 
        BorderThickness="2" 
        ContextMenu="{StaticResource TextBoxContextMenu}"
        Grid.Column="0" 
        Margin="5,10,5,5">
    <TextBlock FontSize="18" 
               FontWeight="Bold"
               HorizontalAlignment="Center" 
               Margin="5" 
               x:Name="Camera" 
               VerticalAlignment="Center" />
</Border>

Наконец, я добавил CommbandBindings в UserControl:

<UserControl.CommandBindings>
    <CommandBinding Command="Copy"                                  CanExecute="CopyCommand_CanExecute" Executed="CopyCommand_Executed" />
    <CommandBinding Command="cs:CarSystemCommands.CopyPlateCommand" CanExecute="CopyCommand_CanExecute" Executed="CopyPlateCommand_Executed" />
</UserControl.CommandBindings>

У меня две проблемы со всем этим на сегодняшний день:

  1. Когда я щелкаю правой кнопкой мыши по элементам управления, я вижу меню, но варианты выбора отображаются серым цветом.У меня есть точки останова, размещенные в начале методов CopyCommand_CanExecute, CopyCommand_Executed и CopyPlateCommand_Executed.Эти точки останова были достигнуты за один раз.Я не знаю, почему они пострадали в то время, но не раньше и не позже.Как сделать так, чтобы метод CanExecute вызывался каждый раз?

  2. В один раз, когда точки останова действительно были получены, свойство Source аргумента было не тем элементом управления, как я думал, абыл UserControl.Мне нужно знать, какой из TextBlocks на UserControl вызвал событие.Как мне это сделать?

Тони

Редактировать:

UserControl также содержит элемент управления ComboBox.Я обнаружил, что методы CanExecute запускаются, когда я щелкаю правой кнопкой мыши на TextBlocks после того, как я раскрываю ComboBox.Мне не нужно ничего выбирать в поле со списком, я просто должен нажать на него.

Есть идеи, что может делать ComboBox, что мой код не так?

Другая вещьявляется то, что после сброса ComboBox, OriginalSource аргументов события Execute является ComboBox.Я хочу использовать одну и ту же команду «Копировать» в нескольких текстовых блоках, и мне нужно знать, какое именно контекстное меню использовалось, чтобы я знал, какой текст TextBlock скопировать в буфер обмена.Помогите!

Ответы [ 2 ]

0 голосов
/ 29 мая 2013

Эта проблема была решена в моем коде. Оказалось, что проблема заключалась в том, что процессор XAML не смог определить, какова цель команд. То есть он не мог понять, куда отправить команду.

Мне удалось исправить это с помощью кода в моем коде позади. Я все еще заинтересован в решении XAML для этой проблемы, но у меня не было времени, чтобы разобраться с ним. В то же время решение, которое я реализовал, работает нормально.

Для тех, кто заинтересован, вот код, который я написал, который устанавливает цель команды:

private void FixMenuItems( FrameworkElement element, Func<MenuItem, bool> condition ) {
    foreach ( MenuItem menuItem in element.ContextMenu.Items ) {
        if ( condition( menuItem ) ) {
            menuItem.CommandTarget = this;
        }
    }
}

Чтобы использовать функцию, вы передаете ссылку на элемент управления с контекстным меню, которое вы пытаетесь исправить в методе, вместе с функцией, которая принимает MenuItem в качестве параметра, возвращает true, если свойство MenuItem's CommandTarget должен быть установлен на текущий объект.

0 голосов
/ 27 января 2012

Я нашел частичный ответ на мою проблему. Я выяснил, каким образом мой код может определить, какая команда TextBlock была выполнена из ContextMenu. Вместо использования общего ContextMenu для трех TextBlocks, которым нужна эта команда, я создал отдельное ContextMenu для каждого TextBlock. Затем я добавил CommandParameter в пункт меню Копировать для этого TextBlock с именем свойства, которое я хотел скопировать. Затем в обработчике события CopyCommand_Executed я проверяю значение значения e.Parameter и копирую значение соответствующего элемента управления в буфер обмена. Это прекрасно работает.

Однако моя проблема с событиями CanExecute, которые не запускаются, пока я не выберу что-то в ComboBox, остается. Мне все еще нужно выяснить это.

Edit:

Что ж, теперь все работает нормально, включая события CanExecute. Я пробовал разные вещи, которые, должно быть, что-то ломали, но теперь, когда у меня работает CommandParameter, все остальное кажется нормальным. Я собираюсь отметить это как ответ.

Второе редактирование:

Ну, вообще-то, все работает на UserControl, над которым я работал, когда я публиковал это. Но все еще есть проблемы.

Упомянутый выше UserControl фактически встроен в другой UserControl. Первый контент UserControl содержится в StackPanel; Я установил StackPanel в качестве FocusScope, и, похоже, именно тогда все начало работать.

Второй элемент управления имеет StackPanel в корне и несколько сеток внутри него. Первый Grid содержит первый UserControl и некоторые другие вещи. Вторая Grid ниже, которая имеет две DataGrids с ContextMenus. Это ContextMenus, которые сейчас не работают.

Я сделал StackPanel FocusScope. Контекстные меню в первом UserControl не работают, если я не сделаю его FocusScope, поэтому он тоже один. Наконец, я сделал Grid, который содержит две DataGrids, FocusScope.

Я думаю, что проблема связана с FocusScopes, но я понятия не имею, как это связано, и никакая комбинация, которую я пробовал, не работает. Есть идеи?

...