none
Wierd Enter/Leave/Validating behavior in a WPF control hosted within a Winform RRS feed

  • Question

  • I am working on a WinForms app which is being migrated in parts to WPF so there is a mix of Winforms and WPF.

    The problem: On a win form with a WPF control hosted via ElementHost, When focus shifts from a win forms text box to a WPF control (say text box), the Validating event of the win forms text box gets called such that the validation fails (e.Cancel = true), then instead of the focus being set to the win forms text box, the EnterLeave and Validating event keeps on calling repeatedly on the WinForms text box. Note that i am calling a Winforms message box in the validating event and if the user presses Cancel button, the validating event is set to cancelled. In my code sample, the user presses Cancel each time and ideally the focus should go back to the originating winforms text box.

    I have isolated the problem that I am facing and put a sample here. So here's what I have. A Win Forms app with two text boxes,

    text box1 - Validating event written on this one allows simulating a validation failure by setting Cancel property on event argument

    text box2 - As a demo to show the behavior when focus is changed from textbox1 to another winform control

    Panel - Hosts Wpf control containing a text box via ElementHost

    The code looks like this:

    Winforms

       private void WindowsFormTestLoad(object sender, EventArgs e)
        {
            // Host WPF UserControl in winforms
            UserControl1 ctrl = new UserControl1();
            host = new ElementHost { Dock = DockStyle.Left , Child = ctrl};
            this.panel1.Controls.Add(host);
        }
    
        // Textbox1 events
        private void TextBox1Enter(object sender, EventArgs e)
        {
            Debug.WriteLine("Enter: text box 1");
        }
    
        private void TextBox1Leave(object sender, EventArgs e)
        {
            Debug.WriteLine("Leave: text box 1");
        }
    
        // Show a win form message box with OK and Cancel buttons.
        // Clicking on Cancel simulates a validation failure (This is what happens in my application).
        private void TextBox1Validating(object sender, CancelEventArgs e)
        {
            Debug.WriteLine("Validating: text box 1");
    
            var dialog = System.Windows.Forms.MessageBox.Show("blah blah", "caption", MessageBoxButtons.OKCancel);
            if (dialog == DialogResult.Cancel)
            {
                e.Cancel = true;
            }
        }

    WPF Control

        <UserControl x:Class="WpfWinformInterop.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="300" d:DesignWidth="300">
    <StackPanel>
        <TextBox Name="txt1"></TextBox>
    </StackPanel>

    When I try to shift focus to a Winform control (say text box), the Validating event is fired only once and focus gets back to the original text box.

    The debug output when switching to a win forms text box (text box 1 to text box 2) is:
    Leave: text box 1

    Validating: text box 1

    Enter: text box 1

    When i try to move focus from win form to WPF the validating event on win form's text box keeps on firing.

    The debug output when switching to a WPF control is:

    Leave: text box 1

    Validating: text box 1

    Enter: text box 1

    Leave: text box 1

    Validating: text box 1

    Enter: text box 1

    Leave: text box 1

    Validating: text box 1

    goes on and on like this ...

    I fail to understand why WPF behavior is different and what can be done to make it behave similarly to the win forms version. Any help would be greatly appreciated.



    Friday, June 30, 2017 8:53 AM

All replies

  • Hi Dhananjay  Kher,

    According to your sample you shown, I can not reproduce your issue, When I try to move focus from winform textBox to WPF textbox, the validating event on winform's textBox not  keeps on firing.

    I think you must have something not mentioned, or I have something misunderstanding.

    Can you upload your demo (which reproduce the issue) to OneDrive(Including your test material). We can download it and debugging. This will help us quickly analyze your problem.

    And some advices I would  suggests:

    If you are ready to migrate Winform program to WPF, so I think you should try your best to use WPF controls, WPF has a wealth of controls to meet your needs. You need create WPF project,rather than Winform project.

    We do not guarantee winform‘s each control can have a good performance in the WPF.

    If this problem persists, I think you can  get around it, only use WPF TextBox control, or only use WinForm TextBox, because the WPF TextBox control does not have Leave and Enter events.

    Best Regards,

    Bob


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.





    Monday, July 3, 2017 2:54 AM
    Moderator
  • Hi Bob,

    I will try to post the sample code solution in day.

    Just to clear, in the validating event, i am using a winforms messagebox. This is how our application currently runs.

    Have you added that call when you tried to reproduce the issue? 

    // Show a win form message box with OK and Cancel buttons.
        // Clicking on Cancel simulates a validation failure (This is what happens in my application).
        private void TextBox1Validating(object sender, CancelEventArgs e)
        {
            Debug.WriteLine("Validating: text box 1");
    
            var dialog = System.Windows.Forms.MessageBox.Show("blah blah", "caption", MessageBoxButtons.OKCancel);
            if (dialog == DialogResult.Cancel)
            {
                e.Cancel = true;
            }
        }


    Monday, July 3, 2017 5:26 AM