在 WPF 中,如何在 WindowsFormsHost 上画一条线?

发布于 2024-07-24 08:42:03 字数 1172 浏览 8 评论 0原文

这是我的 XAML

<Grid
    Name="grid">
    <TextBlock
        Text="Some Label" />
    <WindowsFormsHost
        Name="winFormsHost">

    </WindowsFormsHost>
</Grid>

在加载表单时我执行以下方法

protected void OnLoad(object sender, RoutedEventArgs e)
{
    // Create a line on the fly
    Line line = new Line();

    line.Stroke = Brushes.Red;
    line.StrokeThickness = 17;

    line.X1 = 50;
    line.Y1 = 50;

    line.X2 = 250;
    line.Y2 = 50;

    this.grid.Children.Add(line);

    System.Windows.Forms.TextBox oldSchoolTextbox = new System.Windows.Forms.TextBox();
    oldSchoolTextbox.Text = "A bunch of Random Text will follow.  ";
    oldSchoolTextbox.WordWrap = true;
    oldSchoolTextbox.Width = 300;

    for (int i = 0; i < 250; i++)
    {
        oldSchoolTextbox.Text += "abc ";

        if (i % 10 == 0)
        {
            oldSchoolTextbox.Text += Environment.NewLine;
        }
    }

    this.winFormsHost.Child = oldSchoolTextbox;
}

该线仅在我注释掉以下行时绘制。

this.winFormsHost.Child = oldSchoolTextbox;

如何在 WindowsFormsHost 控件上画一条线?

Here is my XAML

<Grid
    Name="grid">
    <TextBlock
        Text="Some Label" />
    <WindowsFormsHost
        Name="winFormsHost">

    </WindowsFormsHost>
</Grid>

On the load of the form I execute the following method

protected void OnLoad(object sender, RoutedEventArgs e)
{
    // Create a line on the fly
    Line line = new Line();

    line.Stroke = Brushes.Red;
    line.StrokeThickness = 17;

    line.X1 = 50;
    line.Y1 = 50;

    line.X2 = 250;
    line.Y2 = 50;

    this.grid.Children.Add(line);

    System.Windows.Forms.TextBox oldSchoolTextbox = new System.Windows.Forms.TextBox();
    oldSchoolTextbox.Text = "A bunch of Random Text will follow.  ";
    oldSchoolTextbox.WordWrap = true;
    oldSchoolTextbox.Width = 300;

    for (int i = 0; i < 250; i++)
    {
        oldSchoolTextbox.Text += "abc ";

        if (i % 10 == 0)
        {
            oldSchoolTextbox.Text += Environment.NewLine;
        }
    }

    this.winFormsHost.Child = oldSchoolTextbox;
}

The line only draws when I comment out the following line.

this.winFormsHost.Child = oldSchoolTextbox;

How do I draw a line over the WindowsFormsHost control?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

倾城泪 2024-07-31 08:42:03

微软有一种称为“空域”的东西可以防止这种情况发生,至少很容易。 以下是描述空域的 WPF 互操作页面。 [它具有 DX 焦点,但正如所述,同样的情况也适用于 WindowsFormsHost。]

WindowsFormsHost(当它有子级时)创建一个单独的 HWND,这会阻止 WPF 呈现上下文在该矩形中显示。

解决此问题的最佳选择需要 .NET 3.5sp1(至少要可靠地工作)。 您可以通过创建一个完全独立的、100% 透明的背景窗口并将其放置在 Windows 窗体主机控件上来解决此问题。 然后你画进去,它就会正确显示。

这有点老套的感觉,但确实有效。

There is something Microsoft has called "airspace" that prevents this from happening, at least easily. Here is the WPF Interop page describing airspace. [It has a DX focus, but the same thing applies, exactly as stated, to WindowsFormsHost.]

WindowsFormsHost (when it has a child) creates a separate HWND, which prevents the WPF rendering context from displaying in that rectangle.

The best option for working around this requires .NET 3.5sp1 (at least to work reliably). You can get around this by creating an entirely separate, 100% transparent background window, and placing it over your windows forms host control. You then draw into that, and it will display correctly.

It's somewhat hacky feeling, but it works.

俯瞰星空 2024-07-31 08:42:03

我遇到了同样的问题,经过彻底搜索后,最终也使用了 WindowsFormsHost 顶部的透明“覆盖”窗口。 要保持主窗口与覆盖窗口同步,您需要处理以下事件:

MainWindow 的 LocationChanged 事件

WindowsFormsHost 元素的 LayoutUpdated 事件。 这两个事件处理程序都应该调用一个函数,将透明覆盖窗口移动到 WindowsFormsHost 窗口的顶部(下面示例中的 SyncOverlayPosition())。

private void Window_Loaded(object sender, RoutedEventArgs e)
{
   this.LocationChanged += new EventHandler(MainWindow_LocationChanged);
   _windowsFormsHost.LayoutUpdated += new EventHandler(_windowsFormsHost_LayoutUpdated);
}

void MainWindow_LocationChanged(object sender, EventArgs e)
{
   SyncOverlayPosition();
}

void _windowsFormsHost_LayoutUpdated(object sender, EventArgs e)
{
   SyncOverlayPosition();
}

void SyncOverlayPosition()
{
   Point hostTopLeft = _windowsFormsHost.PointToScreen(new Point(0, 0));    

   _overlayWindow.Left = hostTopLeft.X;
   _overlayWindow.Top = hostTopLeft.Y;
   _overlayWindow.Width = _windowsFormsHost.ActualWidth;
   _overlayWindow.Height = _windowsFormsHost.ActualHeight;
}

I've had the same problem, and after searching all over also ended up using the transparent 'overlay' window on top of the WindowsFormsHost. To keep your main window synchronized with the overlay window you need to handle the following events:

LocationChanged event for your MainWindow
and
LayoutUpdated event for your WindowsFormsHost element. Both these event handlers should call a function that moves your transparent overlay window on top of the WindowsFormsHost window (SyncOverlayPosition() in the example below).

private void Window_Loaded(object sender, RoutedEventArgs e)
{
   this.LocationChanged += new EventHandler(MainWindow_LocationChanged);
   _windowsFormsHost.LayoutUpdated += new EventHandler(_windowsFormsHost_LayoutUpdated);
}

void MainWindow_LocationChanged(object sender, EventArgs e)
{
   SyncOverlayPosition();
}

void _windowsFormsHost_LayoutUpdated(object sender, EventArgs e)
{
   SyncOverlayPosition();
}

void SyncOverlayPosition()
{
   Point hostTopLeft = _windowsFormsHost.PointToScreen(new Point(0, 0));    

   _overlayWindow.Left = hostTopLeft.X;
   _overlayWindow.Top = hostTopLeft.Y;
   _overlayWindow.Width = _windowsFormsHost.ActualWidth;
   _overlayWindow.Height = _windowsFormsHost.ActualHeight;
}
农村范ル 2024-07-31 08:42:03

接受的答案确实有效。 然而,唯一的问题是透明窗口将显示在我的主窗口上。 我还必须参与运动以确保一切保持同步。

我做了一些与透明窗口略有不同的事情。 这对我的情况有效,但可能并不总是有效。

我创建了一个 Windows 窗体用户控件。 我将文本框和线条图放在 Windows 窗体用户控件上。 然后,我可以在其上进行绘制并使用 WindowsFormsHost 在 WPF 应用程序中显示。

The accepted answer does work. However the only issue with it is that the transparent window would be displayed over my main window. I also had to hook into movement to make sure everything stayed in sync.

I did something slightly different than a transparent window. This worked in my case, but may not always work.

I created a Windows Form user control. I put the textbox and the line drawing on the windows form user control. This then enabled me to draw over it and display in a WPF application using the WindowsFormsHost.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文