【问题标题】:Adding WPF controls on WindowsFormsHost?在 WindowsFormsHost 上添加 WPF 控件?
【发布时间】:2015-02-18 06:33:47
【问题描述】:

如何在 WindowsFormsHost 上添加 WPF 控件(我已经知道,当我将 Child 添加到 WFH 时,它会变成一个单独的句柄)。我尝试将其设置为单独的 StackPanel 或 Canvas,但似乎不起作用:

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" });

}
}

有没有其他方法可以在不使用 hacky 透明 Windows hack 的情况下在 WindowsFormsHost 上添加 WPF 控件?谢谢。

【问题讨论】:

  • @GrantWinney 因为Image() 不能在后台播放动画GIF,我可以使用MediaPlayer()MediaTimeline() 来执行此操作,但我不希望我的程序继续消耗20% 的 CPU 用于永久播放 Media 元素。如果我使用 PictureBox,它可以比 WPF 的MediaPlayer() 更流畅、更快地播放 GIF,并且默认播放(设置背景路径,完成。)
  • 所以我很清楚,你想要你的 WPF 应用程序中的 WFH; WFH 将主持一个 WinForms PictureBox;但是你想在上面叠加 WPF 元素?如果是这样,我认为这是不可能的。与原生 Windows 和 WinForms 不同,WPF 有一个呈现的窗口。我曾经托管过 WinForms 图表控件,并且无法在图表的 Z 顺序前放置 WPF 内容
  • @MickyDuncan 正是 Hugs ^_^
  • @user3718577 哈哈。祝你好运! :)
  • @MickyDuncan 谢谢:D 我得到了解决方案:D

标签: c# wpf


【解决方案1】:

在 C# 程序代码中制作了一些东西之后,我想在主机上添加主机,等等……所以我可以在 WinForms 控件上添加 WPF 控件,覆盖 WPF 控件……有点奇怪东西,但你可以自己尝试,如果你在添加时没有定义ElementHostWindowsFormsHost 大小,请注意.NET 中存在一些小错误。示例:

/*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);


    }
}

【讨论】:

    【解决方案2】:

    好吧,这更近了…… 将 Windows 窗体用户控件添加到您的项目:

    在该用户控件中添加您的图像:

    现在返回 XAML 并添加 WFH... 添加您刚刚创建的用户控件的子项。

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

    注意标记中标签的偏移量是这样的,它可以放在画布上你想要的任何地方。

    结果是这样,但它没有动画......

    【讨论】:

    • 当您说句柄时,我认为这意味着您可以让用户抓取。在这种情况下,您必须使用装饰器。
    • 如果我有足够的投票权,我会因为你的努力而给你 +1,但你在同一点上得到了:“你不能在图片框上添加控件”。但是没关系,我已经通过在原始窗口上使用透明窗口来解决它。无论如何,谢谢! :3
    • John,虽然不错,但它并没有解决 OP 关于如何在PictureBox前面显示 WPF 元素的要求。 “This is Bill Clinton”应该出现在PictureBox 的Z 顺序之上。即在前面;透明/过度。您只是在 WPF 窗口中托管一个 WinForms 控件。
    • @user3718577 如果您有解决方案,可以将其添加为问题的答案,以供未来有类似问题的用户使用。
    • 米奇;该解决方案确实显示了标签如何覆盖图像,它是解决方案中提到的偏移量的函数。无需在顶部放置另一个窗口,因为偏移量用于将文本放置在想要的任何位置。这是装饰层背后的基本原理。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-13
    相关资源
    最近更新 更多