У меня есть ситуация, когда мне нужно обработать некоторую комбинацию клавиш, и у меня есть следующая структура приложения с использованием ElementHost и WindowsFormsHost (эту структуру нельзя изменить)
Winform App --> (ElementHost) --> Wpf Control --> (WindowsFormsHost) --> WinForm Control
Есть несколько ярлыков, которые обрабатываются на уровне WinForm Control
с помощью переопределения ProcessCmdKey(ref Message msg, Keys keyData)
.
Также есть глобальные сочетания клавиш, которые обрабатываются на уровне WinForm App
с использованием переопределения ProcessCmdKey(ref Message msg, Keys keyData)
(пример: F3 )
Задача
Когда WinForm Control
находится в фокусе, нажатие F3 / любая клавиша вызывает только WinForm Control
метод ProcessCmdKey
при включении переходит к соответствующему событию нажатия клавиши управления.
Событие препроцессора не достигает Wpf Control
OnPreviewKeyDown
или Winform App
ProcessCmdKey
. Поэтому Winform App
не имеет возможности работать с ключом.
Другие наблюдения
- Если
Wpf Control
находится в фокусе, нажатие любой клавиши вызывает следующие события
Wpf Control's OnPreviewKeyDown() --> Winform App's ProcessCmdKey()
- Если элемент управления WPF размещен в приложении WPF, события работают должным образом.
WinForm Control's ProcessCmdKey() -> WPF App Window's PreviewKeyDown() -> WpfControl's PreviewKeyDown()
Я пытался вызвать PreviewKeyDown
событие элемента управления WindowsFormsHost
из Winform Control
метода ProcessCmdKey (). PreviewKeyDown
срабатывает на слое WPF, но не вызывает ProcessCmdKey
из Winform App
Я пытался использовать SendMessage
для отправки сообщения в очередь сообщений Winform App с WinForm Control
, но безуспешно.
Похожие проблемы
WinFormApp
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
ElementHost host = new ElementHost();
host.Dock = DockStyle.Fill;
host.Child = new WpfControl();
this.Controls.Add(host);
}
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
return base.ProcessCmdKey(ref msg, keyData);
}
}
WPFControl.xaml
<UserControl x:Class="App.WpfControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:App"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="124*" />
<ColumnDefinition Width="388*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="2*" />
</Grid.RowDefinitions>
<Label Grid.Row="0" Grid.Column="0" Content="value1" Height="28" HorizontalAlignment="Left" Name="value1" VerticalAlignment="Top" />
<TextBox Grid.Row="0" Grid.Column="1" Height="23" HorizontalAlignment="Left" Name="textBox1" VerticalAlignment="Top" Width="257" />
<WindowsFormsHost Grid.Column="1" Grid.Row="2" Height="90" HorizontalAlignment="Left" Name="windowsFormsHost1" VerticalAlignment="Top" Width="307">
<local:WinControl></local:WinControl>
</WindowsFormsHost>
</Grid>
</UserControl>
WpfControl.cs
public partial class WpfControl : UserControl
{
public WpfControl()
{
InitializeComponent();
}
protected override void OnPreviewKeyDown(KeyEventArgs e)
{
base.OnPreviewKeyDown(e);
}
}
WinControl
public partial class WinControl : UserControl
{
public WinControl()
{
InitializeComponent();
}
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
return base.ProcessCmdKey(ref msg, keyData);
}
}
partial class WinControl
{
private System.ComponentModel.IContainer components = null;
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
private void InitializeComponent()
{
this.HostedLabel = new System.Windows.Forms.Label();
this.txtHost = new System.Windows.Forms.TextBox();
this.SuspendLayout();
//
// HostedLabel
//
this.HostedLabel.AutoSize = true;
this.HostedLabel.Location = new System.Drawing.Point(15, 18);
this.HostedLabel.Name = "HostedLabel";
this.HostedLabel.Size = new System.Drawing.Size(67, 13);
this.HostedLabel.TabIndex = 0;
this.HostedLabel.Text = "HostedLabel";
//
// txtHost
//
this.txtHost.Location = new System.Drawing.Point(107, 18);
this.txtHost.Name = "txtHost";
this.txtHost.Size = new System.Drawing.Size(161, 20);
this.txtHost.TabIndex = 1;
//
// WinControl
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.txtHost);
this.Controls.Add(this.HostedLabel);
this.Name = "WinControl";
this.Size = new System.Drawing.Size(284, 50);
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Label HostedLabel;
private System.Windows.Forms.TextBox txtHost;