1

How could I add WPF controls over a WindowsFormsHost (I already know that when I add a Child to WFH, it becomes a separated handle). I tried making it a separated StackPanel or Canvas but doesn't seem's to work:

class CustomCanvas : Canvas{
public CustomCanvas(/*Some Width, Height, path values received*/){

WindowsFormsHost _AnimatedBckgr = new WindowsFormsHost()
            {
                Width = _wdt,
                Height = Container_Height,
                Margin = new Thickness(0,0,0,0),
                Child = new System.Windows.Forms.Panel()
            };

            ((System.Windows.Forms.Panel)_AnimatedBckgr.Child).Controls.Add(new System.Windows.Forms.PictureBox()
            {
                //Width = (int)_wdt, Height = (int)Container_Height,
                Dock = System.Windows.Forms.DockStyle.Fill,
                BackgroundImage = new System.Drawing.Bitmap(GifAnimatedFilePath),
                BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch,
            });
//StackPanel or Canvas wndHost;
            wndHost = new StackPanel() { Width = _wdt, Height = Container_Height };
            wndHost.Children.Add(_AnimatedBckgr);

            Children.Add(wndHost); 
//Anything added in this canvas doesn't appears over the wndHost
            Children.Add(new Button(){ Content = "Hi" });

}
}

Is there any other way to add WPF controls over the WindowsFormsHost without using the hacky transparent Windows hack? Thanks.

3
  • 1
    @GrantWinney Because Image() cannot play animated GIF's in background, instead I could use a MediaPlayer() or MediaTimeline() to make this move, but I don't want my program to keep consuming over 20% CPU in just playing a Media element permanently. If I use a PictureBox it can play a GIF smooth and faster than WPF's MediaPlayer() and this is played by default (Set Background path, done.) Commented Feb 17, 2015 at 1:28
  • So I have this clear, you want the WFH in your WPF app; the WFH will host a WinForms PictureBox; but then you want to superimpose WPF elements on top of that? If so I don't think it is possible. WPF has a single rendered window as opposed to native Windows and WinForms. I once hosted the WinForms Chart control and was unable to have WPF things in front of the Z-order of the chart Commented Feb 17, 2015 at 1:54
  • @MickyDuncan Exactly that <3 Jajajaja And I know... I could do the trick of adding a borderless transparent nonresizable Window over the Window with the WFH and add everything else over that but... Looks kind of dirty to do that (?) jajaja Anyways, thanks, I will keep trying on making some other black magic in the C# code. If I can't I will do the trick of the wnd, anyways, thanks :DD Hugs ^_^ Commented Feb 17, 2015 at 2:02

2 Answers 2

1

Ok this is closer... Add a Windows Form User Control to your project:

enter image description here

In that user control add your image:

enter image description here

Now go back to XAML and add the WFH... adding in a child of the usercontrol you just created.

<Canvas>
  <WindowsForsHost HorizontalAlignment="Left" Height="34" VerticalAlignment="Top" Width="52">
    <local:UserControl1/>
  </WindowsformsHost>
  <Label Margin="0,35,-13,0">This is bill Clinton</Label>
</Canvas>

Notice in the markup the offset of the label was such that it can be put anywhere you want on the canvas.

The Result is this but it don't animate....

enter image description here

Sign up to request clarification or add additional context in comments.

6 Comments

When you say handle I take that to mean something you can have user grab. In that case you have to use an adorner.
If I had enough to vote up I'll give you +1 because of your effort, but you got at the same point: "You can't add a control OVER the picturebox". But is okay, I already solved it by using a transparent Window over the original one. Anyways, thanks! :3 <3
John, while not bad it does not address OP's requirement of how to show a WPF element in front of the PictureBox. "This is Bill Clinton" should appear on top of the Z-order of the PictureBox. i.e. infront; transparent/overly. You are just hosting a WinForms control inside a WPF window.
@user3718577 If you've got a solution, can you add it as an answer to the question for future users with a similar problem.
Mickey; The solution does show how the label can overwrite the image, it's a function of the offset as mentioned in the solution. There's no need to put another window over the top as offsets are used to place the text anywhere one wants. This is the underlying principal behind adorner layers.
|
1

After making some stuff in the C# procedural code, I tought of adding a Host over a host, and so over... So I can add WPF controls over the WinForms Controls overriding a WPF Control... Some kind of weird stuff, but you can try it by your own, notice there are sme bugs in .NET if you don't define the ElementHost or WindowsFormsHost size at adding time. Example:

/*In a WPF Window, content container being a Canvas, adding a new WFH with
a `PicturBox()` on it. Then add it a DataGridView OVER this one, and then,
some `Label` over it*/

 public partial class MainWindow : Window
{
    public MainWindow()
    {
        Content = new Canvas();

        System.Windows.Forms.Integration.WindowsFormsHost _wndHost = new System.Windows.Forms.Integration.WindowsFormsHost()
        {
            Margin = new Thickness(0, 0, 0, 0),
            Width = 200,
            Height = 200,
            Child = new System.Windows.Forms.PictureBox()
            {
                BackgroundImage = new System.Drawing.Bitmap(System.IO.Directory.GetCurrentDirectory() + "\\f.jpg"),
                BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch
            }
        };

        ((System.Windows.Forms.PictureBox)_wndHost.Child).Controls.Add(new System.Windows.Forms.DataGridView()
        {
            Width = 170, Height = 70,
            ColumnCount = 2, RowCount = 2
        });

        ((System.Windows.Forms.PictureBox)_wndHost.Child).Controls.Add(new System.Windows.Forms.Integration.ElementHost()
        {
            Width = 70, Height = 15,
            Child = new TextBlock()
            {
                Width = 10,
                Height = 10,
                Text = "First :O",
                Foreground = Brushes.Red,
                Background = Brushes.Transparent
            },
            BackColor = System.Drawing.Color.Transparent,
            Location = new System.Drawing.Point(10, 100)
        });

        ((System.Windows.Forms.PictureBox)_wndHost.Child).Controls.Add(new System.Windows.Forms.Integration.ElementHost()
        {
            Width = 70, Height = 15,
            Child = new TextBlock()
            {
                Width = 10,
                Height = 10,
                Text = "Second :O",
                Foreground = Brushes.Red,
                Background = Brushes.Transparent
            },
            BackColor = System.Drawing.Color.Transparent,
            Location = new System.Drawing.Point(10, 150)
        });

        ((Canvas)Content).Children.Add(_wndHost);


    }
}

Solution

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.