C# 在WPF中动态添加键绑定

C# 在WPF中动态添加键绑定,c#,wpf,mvvm,C#,Wpf,Mvvm,是否可以基于绑定的数据源动态定义键绑定?我有一个带有网格的屏幕,我允许用户为它保存各种布局。我当前将grids上下文菜单绑定到布局名称(通过ViewModel),允许它们通过菜单切换布局 但是,我希望将每个布局与快捷键相关联。由于快捷键是由用户定义的,我不能简单地在窗口XAML中添加大量的元素。另一个问题是绑定需要提供布局的名称作为命令参数 有没有办法从动态源动态创建一系列元素 作为测试,我已将绑定静态添加到我的视图XAML中,它们工作正常,但这只是为了测试我的概念: <UserContr

是否可以基于绑定的数据源动态定义键绑定?我有一个带有网格的屏幕,我允许用户为它保存各种布局。我当前将grids上下文菜单绑定到布局名称(通过ViewModel),允许它们通过菜单切换布局

但是,我希望将每个布局与快捷键相关联。由于快捷键是由用户定义的,我不能简单地在窗口XAML中添加大量的
元素。另一个问题是绑定需要提供布局的名称作为命令参数

有没有办法从动态源动态创建一系列
元素

作为测试,我已将绑定静态添加到我的视图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>

有几种方法可以做到这一点,最简单的方法是创建一个转换器,它将根据命令名返回一个键(本质上是一种查找,布局名为键,键为值)。如果您需要处理更复杂的访客,它会变得更复杂,我会为它制作一个示例:

以下是XAML:

<Grid.InputBindings>
<KeyBinding Key="{Binding Converter={StaticResource converter}, ConverterParameter=My Other Layout Name}" Command="{Binding MyCommand}" />
</Grid.InputBindings>

以下是我用来动态创建键绑定的代码,作为允许在热键上执行代码段的代码段编辑器的一部分

除了前面的示例之外,它还演示了如何解析按键组合的用户输入:

// 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);

您可以使用相同的实现来处理复杂的来宾对象(Ctrl+Alt+_-Blah等),请参见:其中大部分可以替换为以下内容(不需要手动解析所有这些内容):kb=new KeyBinding(命令,new KeyGestureConverter().ConvertFromString(ksc)作为键手势);