Pergunta

Aqui está o meu XAML

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

    </WindowsFormsHost>
</Grid>

Na carga de forma eu executar o seguinte método

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

A linha só chama quando eu comente a seguinte linha.

this.winFormsHost.Child = oldSchoolTextbox;

Como faço para desenhar uma linha sobre o controle WindowsFormsHost?

Foi útil?

Solução

Não é algo que a Microsoft chama de "espaço aéreo" que impede que isso aconteça, pelo menos facilmente. Aqui está a WPF página Interop descrevendo o espaço aéreo . [Ele tem um foco DX, mas a mesma coisa se aplica, exatamente como foi dito, a WindowsFormsHost.]

WindowsFormsHost (quando se tem um filho) cria um HWND separado, o que impede o contexto de renderização WPF de exibir naquele retângulo.

A melhor opção para trabalhar em torno deste requer .NET 3.5SP1 (pelo menos para o trabalho de forma confiável). Você pode contornar isso criando um 100% janela de fundo totalmente separado, transparente, e colocá-lo sobre o seu controle de host Windows Forms. Você, então, desenhar em que, e ele irá exibir corretamente.

É sentimento um pouco hacky, mas funciona.

Outras dicas

Eu tive o mesmo problema, e depois de pesquisar em todo também acabou usando a janela transparente 'sobreposição' no topo da WindowsFormsHost. Para manter a sua janela principal sincronizado com a janela de sobreposição você precisa lidar com os seguintes eventos:

LocationChanged evento para a sua MainWindow e evento LayoutUpdated para o seu elemento WindowsFormsHost. Ambos estes manipuladores de eventos deve chamar uma função que move sua janela sobreposição transparente na parte superior da janela do WindowsFormsHost (SyncOverlayPosition () no exemplo abaixo).

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

A resposta aceita funciona. No entanto, o único problema com isso é que a janela transparente seria exibido por cima do meu janela principal. Eu também tive que ligar para movimento para se certificar que tudo ficou em sincronia.

Eu fiz algo um pouco diferente do que uma janela transparente. Isso funcionou no meu caso, mas pode não funcionar sempre.

Eu criei um controle de usuário Windows Form. Coloquei a caixa de texto e o desenho de linha nas janelas formar controle do usuário. Isso, então, permitiu-me para desenhar sobre ele e exibição em um aplicativo WPF usando o WindowsFormsHost.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top