Динамически добавлять привязки клавиш в WPF - PullRequest
5 голосов
/ 16 февраля 2011

Можно ли динамически определять привязки клавиш на основе связанного источника данных? У меня есть экран с сеткой, и я разрешаю пользователям сохранять для него различные макеты. В настоящее время я связываю контекстное меню сетки с именами макетов (через ViewModel), позволяя им переключать макеты через меню.

Однако я бы хотел связать каждую раскладку с сочетанием клавиш. Поскольку сочетания клавиш определяются пользователем, я не могу просто добавить количество элементов <KeyBinding> в окне XAML. Другая проблема заключается в том, что для привязки потребуется указать имя макета в качестве параметра команды.

Есть ли способ динамически создать серию <KeyBinding> элементов из динамического источника?

В качестве теста я статически добавил привязки к своему XAML-представлению, и они работают нормально, но это было только для проверки моей концепции:

<UserControl.InputBindings>
    <KeyBinding Key="F7" Command="{Binding MyCommand}" CommandParameter="My Layout Name"/>
    <KeyBinding Key="F8" Command="{Binding MyCommand}" CommandParameter="My Other Layout Name"/>
</UserControl.InputBindings>

Ответы [ 2 ]

2 голосов
/ 02 февраля 2017

Вот код, который я использую для динамического создания привязок клавиш как часть редактора фрагментов, который позволяет выполнять фрагменты на горячей клавише.

В дополнение к более ранним примерам также демонстрируется, как анализировать пользовательский ввод комбинаций клавиш:

// example key combo from user input
var ksc = "Alt+Shift+M";
ksc = ksc.ToLower();

KeyBinding kb = new KeyBinding();

if (ksc.Contains("alt"))
    kb.Modifiers = ModifierKeys.Alt;
if (ksc.Contains("shift"))
    kb.Modifiers |= ModifierKeys.Shift;
if (ksc.Contains("ctrl") || ksc.Contains("ctl"))
    kb.Modifiers |= ModifierKeys.Control;

string key =
    ksc.Replace("+", "")
        .Replace("-", "")
        .Replace("_", "")
        .Replace(" ", "")
        .Replace("alt", "")
        .Replace("shift", "")
        .Replace("ctrl", "")
        .Replace("ctl", "");

key =   CultureInfo.CurrentCulture.TextInfo.ToTitleCase(key);
if (!string.IsNullOrEmpty(key))
{
    KeyConverter k = new KeyConverter();
    kb.Key = (Key)k.ConvertFromString(key);
}

// Whatever command you need to bind to
// CommandBase here is a custom class I use to create commands
// with Execute/CanExecute handlers
kb.Command = new CommandBase((s, e) => InsertSnippet(snippet),
                             (s,e) => Model.IsEditorActive);

Model.Window.InputBindings.Add(kb);
0 голосов
/ 16 февраля 2011

есть несколько способов сделать это, самый простой из них, imo, - это создать конвертер, который будет возвращать ключ, в зависимости от имени команды (по сути, это поиск с именем макета, являющимся ключом, и ключом, являющимся значением) , Это будет немного сложнее, если вам понадобится обрабатывать более сложные гостевые системы, поприветствуйте, и я напишу образец для этого:

Вот XAML:

<Grid.InputBindings>
<KeyBinding Key="{Binding Converter={StaticResource converter}, ConverterParameter=My Other Layout Name}" Command="{Binding MyCommand}" />
</Grid.InputBindings>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...