2009-06-17 87 views
0

这是我的XAML在WPF中,你如何在WindowsFormsHost上绘制一条线?

<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控件上绘制一条线?

回答

4

微软称之为“空域”,可以防止这种情况发生,至少很容易。这里是WPF Interop page describing airspace。 [它有一个DX焦点,但同样的东西适用于WindowsFormsHost。]

WindowsFormsHost(当它有一个孩子时)创建一个单独的HWND,它阻止WPF渲染上下文在该矩形中显示。

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

这有点冒失的感觉,但它的作品。

+0

这是一个小黑客,但它会工作。非常感谢! – 2009-06-17 16:04:04

0

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

我做了一些与透明窗口稍有不同的东西。这工作在我的情况,但可能并不总是工作。

我创建了一个Windows窗体用户控件。我把文本框和线条图放在窗体用户控件上。这使我可以绘制它并使用WindowsFormsHost显示在WPF应用程序中。

2

我遇到过同样的问题,并且遍历搜索后也最终使用WindowsFormsHost顶部的透明“覆盖”窗口。为了跟上,你需要处理以下事件叠加窗口同步你的主窗口:

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