控制在WinForm应用程序上单击在ElementHost中托管的WPF控件时的验证问题

时间:2013-06-25 22:09:01

标签: wpf-controls

我有一个winform应用程序,其中包含在ElementHost上托管的Winform和WPF控件。当winform文本框进入验证因为单击了WPF控件并且存在验证错误时,ElementHost会一直触发Focus事件,这会使我的应用程序卡住。

如果有办法解决,请提供建议。

我创建了一个示例应用程序来复制问题。

我有一个Form1,包含2个winform文本框(textbox1,textbox2)和一个托管在ElementHost上的WPF控件。

textbox1_validating事件处理程序检查输入是否为“1”,然后通过将事件参数e.Cancel设置为true来取消事件。如果textbox1进入验证,这很有效,因为点击了其他winform控件。

但是,如果由于WPF控件增益焦点而使textbox1进入验证状态,则取消事件不起作用。 ElementHost持续触发Focus事件导致textbox1_validating一次又一次地被调用。

UserControl代码:

<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>

WinForm代码:

    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++;
            if (Form1.HasError)
                return;

        }
        else if (m.Msg == WM_KILLFOCUS)
        {
            KillFocusFiredCount++;
        }

        base.WndProc(ref m);
    }
}

0 个答案:

没有答案