如何将快捷方式从 MainWindow 传递到 ContentControl 中的 UserControl?
How to pass shortcuts from MainWindow to the UserControl in ContentControl?
在我的 Window 中动态加载到 ContentControl 的 UserControl 不接收在 UserControl XAML 内部定义的键盘快捷键,以防它没有获得焦点。
我需要在不聚焦 UserControl 的情况下为动态加载的 UserControl 实现键盘快捷键。
我无法在 MainWindow 上定义 InputBindings,因为 InputBindigs 的变化取决于当前加载的 UserControl。
1) 所以我尝试通过 RaiseEvent 将所有 Window_KeyUp 发送到加载的 UserControl,但没有成功。 (Whosebug 异常或未调用任何操作)
2) 当 UserControl 已加载到 ContentControl 时,我还尝试通过 LoadedUserControl.InputBindings 填充 MainWindow.InputBindings... 运气不好(定义的命令在上下文中未知)
UserControl.xaml
----------------
<UserControl.InputBindings>
<KeyBinding Key="N" Command="{Binding Path=NewOrderCommand}" Modifiers="Control" />
</UserControl.InputBindings>
如果 UserControl 获得焦点,这将起作用。
所以为了摆脱焦点,我尝试了这个:
MainWindow.xaml.cs
-------------------
private void MainWindow_KeyUp(object sender, System.Windows.Input.KeyEventArgs e)
{
// ModulePanel points to the loaded UserControl
ViewModel.CurrentModule.ModulePanel.RaiseEvent(e);
e.Handled = true;
}
所以这发出了 WhosebugException
我试过设置e.Handled = true;在 RaiseEvent(e) 之前,但它不会将事件传递给 UserControl - 所以什么也没有发生;
我还尝试将 InputBindings 从 UserControl 获取到 MainWindow:
foreach(InputBinding bi in UserControl.InputBindings)
MainWindow.InputBindings.Add(bi);
但我在调试中遇到异常 window:
找不到目标元素的管理 FrameworkElement 或 FrameworkContentElement。 BindingExpression:Path=新订单命令;数据项=空;目标元素是 'KeyBinding' (HashCode=35527846);目标 属性 是 'Command'(类型 'ICommand')
我的期望是,我将动态更改 Window InputBindings 取决于加载的 UserControl,其中定义了 InputBindings。
尝试将 ViewModel 用作 DataContext,并让它们使用 Messenger 相互通信。您可以将所需的信息发送到未获得焦点的 Usercontrol 的 ViewModel。
如果您想坚持使用代码隐藏,请订阅 Mainwindow 上的事件处理程序:
PreviewKeyUp += userCtrl.OnKeyUp;
并在您的用户控件中处理它
public void OnKeyUp(object sender, KeyEventArgs e)
{
MyTextBlock.Text = e.Key.ToString();
}
如果您希望 UserControl
能够处理 window 中的所有按键操作,您可以使用 Window.GetWindow
获取对父 window 的引用一旦 UserControl
被加载,然后将事件处理程序连接到它:
public partial class UserControl1 : UserControl
{
public UserControl1()
{
InitializeComponent();
Loaded += (s, e) =>
{
Window parentWindow = Window.GetWindow(this);
parentWindow.PreviewKeyDown += ParentWindow_PreviewKeyDown;
};
Unloaded += (s, e) =>
{
Window parentWindow = Window.GetWindow(this);
parentWindow.PreviewKeyDown -= ParentWindow_PreviewKeyDown;
};
}
private void ParentWindow_PreviewKeyDown(object sender, KeyEventArgs e)
{
//do something...
}
}
在我的 Window 中动态加载到 ContentControl 的 UserControl 不接收在 UserControl XAML 内部定义的键盘快捷键,以防它没有获得焦点。
我需要在不聚焦 UserControl 的情况下为动态加载的 UserControl 实现键盘快捷键。
我无法在 MainWindow 上定义 InputBindings,因为 InputBindigs 的变化取决于当前加载的 UserControl。
1) 所以我尝试通过 RaiseEvent 将所有 Window_KeyUp 发送到加载的 UserControl,但没有成功。 (Whosebug 异常或未调用任何操作)
2) 当 UserControl 已加载到 ContentControl 时,我还尝试通过 LoadedUserControl.InputBindings 填充 MainWindow.InputBindings... 运气不好(定义的命令在上下文中未知)
UserControl.xaml
----------------
<UserControl.InputBindings>
<KeyBinding Key="N" Command="{Binding Path=NewOrderCommand}" Modifiers="Control" />
</UserControl.InputBindings>
如果 UserControl 获得焦点,这将起作用。
所以为了摆脱焦点,我尝试了这个:
MainWindow.xaml.cs
-------------------
private void MainWindow_KeyUp(object sender, System.Windows.Input.KeyEventArgs e)
{
// ModulePanel points to the loaded UserControl
ViewModel.CurrentModule.ModulePanel.RaiseEvent(e);
e.Handled = true;
}
所以这发出了 WhosebugException
我试过设置e.Handled = true;在 RaiseEvent(e) 之前,但它不会将事件传递给 UserControl - 所以什么也没有发生;
我还尝试将 InputBindings 从 UserControl 获取到 MainWindow:
foreach(InputBinding bi in UserControl.InputBindings)
MainWindow.InputBindings.Add(bi);
但我在调试中遇到异常 window:
找不到目标元素的管理 FrameworkElement 或 FrameworkContentElement。 BindingExpression:Path=新订单命令;数据项=空;目标元素是 'KeyBinding' (HashCode=35527846);目标 属性 是 'Command'(类型 'ICommand')
我的期望是,我将动态更改 Window InputBindings 取决于加载的 UserControl,其中定义了 InputBindings。
尝试将 ViewModel 用作 DataContext,并让它们使用 Messenger 相互通信。您可以将所需的信息发送到未获得焦点的 Usercontrol 的 ViewModel。
如果您想坚持使用代码隐藏,请订阅 Mainwindow 上的事件处理程序:
PreviewKeyUp += userCtrl.OnKeyUp;
并在您的用户控件中处理它
public void OnKeyUp(object sender, KeyEventArgs e)
{
MyTextBlock.Text = e.Key.ToString();
}
如果您希望 UserControl
能够处理 window 中的所有按键操作,您可以使用 Window.GetWindow
获取对父 window 的引用一旦 UserControl
被加载,然后将事件处理程序连接到它:
public partial class UserControl1 : UserControl
{
public UserControl1()
{
InitializeComponent();
Loaded += (s, e) =>
{
Window parentWindow = Window.GetWindow(this);
parentWindow.PreviewKeyDown += ParentWindow_PreviewKeyDown;
};
Unloaded += (s, e) =>
{
Window parentWindow = Window.GetWindow(this);
parentWindow.PreviewKeyDown -= ParentWindow_PreviewKeyDown;
};
}
private void ParentWindow_PreviewKeyDown(object sender, KeyEventArgs e)
{
//do something...
}
}