Hi,
I have a winform application on which there is a mix of Winform and a WPF control hosted on ElementHost. When the winform textbox goes into Validating because the WPF control is clicked, and there is validating error, the ElementHost keeps firing Focus event which makes my application stuck.
Please advice if there is a way to resolve it.
I have created a sample application to replicate the issue.
I have a Form1 containing 2 winform textboxes (textbox1, textbox2) and a WPF control hosted on ElementHost.
textbox1_validating event handler checks if input is not "1", then the event is cancelled by setting the event argument e.Cancel to true. This works well if textbox1 goes into validating because other winform control is clicked.
However, if textbox1 goes into validating due to WPF control gains focus, the cancel event does not work. ElementHost keeps firing Focus event causing textbox1_validating been called again and again.
public partial class Form1 : Form { public static bool HasError = false; public Form1() { InitializeComponent(); } private void textBox1_Validating(object sender, CancelEventArgs e) { if (textBox1.Text != "1" && textBox1.Text != "") { MessageBox.Show("Input is invalid, expecting \"1\". "); HasError = true; e.Cancel = true; } } private void InitializeComponent() { this.textBox1 = new System.Windows.Forms.TextBox(); this.textBox2 = new System.Windows.Forms.TextBox(); this.label1 = new System.Windows.Forms.Label(); this.label2 = new System.Windows.Forms.Label(); this.label3 = new System.Windows.Forms.Label(); this._durationCtrlHost = new WindowsFormsApplication1.DurationCtrlHost(); this._durationCtrl = new WpfControlLibrary1.UserControl1(); this.SuspendLayout(); // // textBox1 // this.textBox1.Location = new System.Drawing.Point(120, 23); this.textBox1.Name = "textBox1"; this.textBox1.Size = new System.Drawing.Size(242, 20); this.textBox1.TabIndex = 0; this.textBox1.Enter += new System.EventHandler(this.textBox1_Enter); this.textBox1.Validating += new System.ComponentModel.CancelEventHandler(this.textBox1_Validating); // // textBox2 // this.textBox2.Location = new System.Drawing.Point(121, 56); this.textBox2.Name = "textBox2"; this.textBox2.Size = new System.Drawing.Size(240, 20); this.textBox2.TabIndex = 2; // // label1 // this.label1.AutoSize = true; this.label1.Location = new System.Drawing.Point(24, 30); this.label1.Name = "label1"; this.label1.Size = new System.Drawing.Size(90, 13); this.label1.TabIndex = 4; this.label1.Text = "WinformTextbox1"; // // label2 // this.label2.AutoSize = true; this.label2.Location = new System.Drawing.Point(25, 63); this.label2.Name = "label2"; this.label2.Size = new System.Drawing.Size(90, 13); this.label2.TabIndex = 5; this.label2.Text = "WinformTextbox2"; // // label3 // this.label3.AutoSize = true; this.label3.Location = new System.Drawing.Point(24, 104); this.label3.Name = "label3"; this.label3.Size = new System.Drawing.Size(64, 13); this.label3.TabIndex = 6; this.label3.Text = "WPFControl"; // // _durationCtrlHost // this._durationCtrlHost.Location = new System.Drawing.Point(120, 90); this._durationCtrlHost.Name = "_durationCtrlHost"; this._durationCtrlHost.Size = new System.Drawing.Size(271, 60); this._durationCtrlHost.TabIndex = 3; this._durationCtrlHost.Child = this._durationCtrl; // // Form1 // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(420, 282); this.Controls.Add(this.label3); this.Controls.Add(this.label2); this.Controls.Add(this.label1); this.Controls.Add(this.textBox2); this.Controls.Add(this.textBox1); this.Controls.Add(this._durationCtrlHost); this.Name = "Form1"; this.Text = "Form1"; this.ResumeLayout(false); this.PerformLayout(); } }
public class DurationCtrlHost : ElementHost { private const int WM_SETFOCUS = 0x0007; private const int WM_KILLFOCUS = 0x0008; private int SetFocusFiredCount = 0; private int KillFocusFiredCount = 0; protected override void WndProc(ref Message m) { if (m.Msg == WM_SETFOCUS) { SetFocusFiredCount++; } else if (m.Msg == WM_KILLFOCUS) { KillFocusFiredCount++; } base.WndProc(ref m); } }
<UserControl x:Class="WpfControlLibrary1.UserControl1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" mc:Ignorable="d" d:DesignHeight="54" d:DesignWidth="295"><Grid Height="43"><TextBox Height="20" HorizontalAlignment="Left" Name="textBox1" VerticalAlignment="Top" Width="106" Text="Default1" /><TextBox Height="20" HorizontalAlignment="Left" Margin="130,0,0,0" Name="textBox2" VerticalAlignment="Top" Width="73" Text="Default2" /></Grid></UserControl>