1

Disclaimer: This is not a duplicated post. I googled about the issue. Also read this, this and this SO questions. I tried some of those things but nothing seemed to help.

Consider the following simple example code. It's just an empty ElementHost inside a WinForm (no WPF control inside):

using System.Windows.Forms;
using System.Windows.Forms.Integration;

namespace WindowsFormsApplication15
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            ElementHost host = new ElementHost();
            host.Dock = DockStyle.Fill;
            this.Controls.Add(host);
        }
    }
}

When you resize the form, you can see two black edges at the form border: enter image description here

Please, ¿someone could give a working solution over my example to fix this issue?

Community
  • 1
  • 1
Daniel Peñalba
  • 27,557
  • 31
  • 124
  • 209
  • I found the answer in the following thread: http://stackoverflow.com/questions/1382915/how-to-fix-the-wpf-form-resize-controls-lagging-behind-and-black-background/14309002#14309002 – Daniel Peñalba Jun 08 '16 at 14:26

2 Answers2

2

Try this (same idea as the first link you provided, but better performance):

    public class ElementHost2 : ElementHost {

        public ElementHost2() {
            this.AutoSize = true;
        }

        public override Size GetPreferredSize(Size proposedSize) {
            Form f = this.FindForm();
            Size s = f.ClientSize;
            return s;
        }

        private const uint WM_SETREDRAW = 0xB;

        [DllImport("user32.dll")]
        private static extern int SendMessage(IntPtr hWnd, uint Msg, int wParam, int lParam);

        [DllImport("user32.dll")]
        static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);

        private const uint NOSIZE = 0x0001;
        private const uint NOMOVE = 0x0002;
        private const uint NOZORDER = 0x0004;
        private const uint NOREDRAW = 0x0008;
        private const uint NOACTIVATE = 0x0010;
        private const uint DRAWFRAME = 0x0020;
        private const uint FRAMECHANGED = 0x0020;
        private const uint SHOWWINDOW = 0x0040;
        private const uint HIDEWINDOW = 0x0080;
        private const uint NOCOPYBITS = 0x0100;
        private const uint NOOWNERZORDER = 0x0200;
        private const uint NOREPOSITION = 0x0200;
        private const uint NOSENDCHANGING = 0x0400;
        private const uint DEFERERASE = 0x2000;
        private const uint ASYNCWINDOWPOS = 0x4000;

        protected override void OnResize(EventArgs e) {
            base.OnResize(e);
            SendMessage(this.Handle, WM_SETREDRAW, 0, 0);
            SendMessage(this.Handle, WM_SETREDRAW, 1, 0);
            // forces window to redraw:
            SetWindowPos(this.Handle, IntPtr.Zero, 0, 0, 0, 0, NOSIZE | NOMOVE| NOZORDER | NOACTIVATE | SHOWWINDOW);
        }

        // better performance?
        protected override void OnPaintBackground(PaintEventArgs pevent) {
            //base.OnPaintBackground(pevent);
        }

        protected override void OnPaint(PaintEventArgs e) {
            //base.OnPaint(e);
        }
    }

    class Form2 : Form {
        ElementHost host = new ElementHost2();
        public Form2() {
            Controls.Add(host);
            this.BackColor = Color.Red;
            var p = new System.Windows.Controls.DockPanel();
            p.Background = System.Windows.Media.Brushes.Red;
            host.Child = p;
            p.Children.Add(new System.Windows.Controls.TextBox { Width = 100, Height = 20 });
        }
    }
Loathing
  • 4,776
  • 3
  • 18
  • 29
  • If I insert an WPF control inside this solution now flickers between red and the border color of the docked control, blue in my case. Thanks anyway. – Daniel Peñalba Mar 26 '15 at 14:21
  • Then set the background to blue so they match? – Loathing Mar 26 '15 at 14:23
  • My background should be white, because my WPF control is a white textbox, but the elementhost is painting a blue shadow instead black, because the textbox border (fill docked) is blue. – Daniel Peñalba Mar 26 '15 at 14:33
  • Try your example, adding the textbox FILL instead with a size. The form still flickers! – Daniel Peñalba Mar 26 '15 at 14:40
  • I added the line `Controls.Add(new TextBox { Dock = DockStyle.Fill });` and it is still good for me. – Loathing Mar 26 '15 at 14:51
  • I mean, in the last line of your Form2 class, the following: `p.Children.Add(new System.Windows.Controls.TextBox());` – Daniel Peñalba Mar 26 '15 at 14:57
  • I see. I've been trying to create a workaround by overriding the `WndProc(...)` method in Element2 and intercepting the `WM_WINDOWPOSCHANGING` and `WM_WINDOWPOSCHANGED` messages, but then the WPF textbox stops filling the available space. – Loathing Mar 26 '15 at 16:16
  • Trying to understand the solution given on this post by @jeff, but I was unable to find a solution: http://stackoverflow.com/questions/6501890/elementhost-layout-problems – Daniel Peñalba Mar 26 '15 at 16:24
1

The issue is not related to ElementHost and Winforms. It's just a WPF issue, and I found the answer in the following SO question:

How to fix the WPF form resize - controls lagging behind and black background?

Community
  • 1
  • 1
Daniel Peñalba
  • 27,557
  • 31
  • 124
  • 209