Использование команд WPF с Canvas не работает
У меня есть пользовательский холст, полученный из Canvas
, Он содержит мало ApplicationCommands
лайк New
/Open
/Save
и т.д. добавлено, как это -
this.CommandBindings.Add(new CommandBinding(ApplicationCommands.New, New_Executed,
New_Enabled));
New_Enabled
всегда возвращает истину.
Этот элемент управления используется в проекте wpf, имеющем строку меню; Кнопки меню New/Open/Save находятся в этой строке меню с их Command
установить соответствующий ApplicationCommand
как это -
<syncfusion:SimpleMenuButton
x:Name="NewMenu"
Icon="Images\New_Large.png"
Label="New"
IsEnabled="True"
Command="{x:Static ApplicationCommands.New}"
syncfusion:Ribbon.KeyTip="N">
</syncfusion:SimpleMenuButton>
Команда работает правильно, когда фокус присутствует на Canvas
но как только фокус переключается на другой элемент управления, кнопка "Новый" отключается. Я пробовал настройку CommandTarget
в главное окно, но это тоже не работает.
Почему это происходит и как можно убедиться, что кнопка "Новое меню" будет всегда включена?
2 ответа
@repka - Спасибо за ваш ответ; Я уже пытался использовать имя холста в качестве CommandTarget
но это не работает; Кнопки включаются только тогда, когда фокус находится на холсте, как только я нажимаю на какой-то другой элемент управления в окне, они отключаются. Я также пытался использовать IsFocusScope
но результат тот же. Спасибо за подсказку имени команды.
Я должен был согласиться с этим обходным путем, хотя я не слишком доволен этим -
public WindowMain()
{
InitializeComponent();
//Add commnad bindings
//Need to do this to keep New/Open/Save/Run buttons always enabled
//ToDo:[AJ] Look for better solution then this
this.CommandBindings.Add(new CommandBinding(ApplicationCommands.New, this.TheCanvas.New_Executed, this.TheCanvas.New_Enabled));
this.CommandBindings.Add(new CommandBinding(ApplicationCommands.Open, this.TheCanvas.Open_Executed, this.TheCanvas.Open_Enabled));
this.CommandBindings.Add(new CommandBinding(ApplicationCommands.Save, this.TheCanvas.Save_Executed, this.TheCanvas.Save_Enabled));
this.CommandBindings.Add(new CommandBinding(RTDesignerCanvas.Run, this.TheCanvas.Run_Executed));
}
Проблема в том, что когда ваша кнопка и холст совместно используют область логического фокуса где-то выше в иерархии (скорее всего, это ваше окно), команды, инициированные в некотором меню, никогда не достигают вашего холста.
Если у вас есть только один холст, на который вы хотите получить все ваши команды, просто свяжите CommandTarget
из ваших кнопок на холсте:
...
Command="New"
CommandTarget="{Binding ElementName=TheCanvas}"
...
Обратите внимание, что ICommand
отмечен TypeConverterAttribute
который преобразует строки как "Новый" в ApplicationCommands.New
так что вам не нужно использовать x:Static
расширение разметки.
Вы можете сделать это в одном месте с Style
для всех кнопок на уровне вашего меню / панели инструментов.
Однако, если у вас есть несколько холстов, и вы хотите, чтобы ваша команда была направлена на текущий, вы должны сделать две вещи:
- убедитесь, что ваш холст (или элемент управления) имеет
Focusable="True"
- ограничьте область логического фокуса вашей панели инструментов (или любого контейнера, который вы используете для своих кнопок), установив
FocusManager.IsFocusScope="True"
в теме. Некоторые контейнеры, такие как меню илиToolBar
иметь это по умолчанию. Таким образом, как только алгоритм маршрутизации команд достигнет области действия, он перенаправит его на элемент, в данный момент имеющий фокус клавиатуры.