Question

Voici mon XAML

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

    </WindowsFormsHost>
</Grid>

Au chargement du formulaire, j'exécute la méthode suivante

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

La ligne ne dessine que lorsque je commente la ligne suivante.

this.winFormsHost.Child = oldSchoolTextbox;

Comment tracer une ligne sur le contrôle WindowsFormsHost?

Était-ce utile?

La solution

Il y a quelque chose que Microsoft a appelé "espace aérien". cela empêche que cela se produise, du moins facilement. Voici la page WPF Interop décrivant l'espace aérien . [Il a un focus DX, mais la même chose s’applique, exactement comme indiqué, à WindowsFormsHost.]

WindowsFormsHost (lorsqu'il a un enfant) crée un HWND distinct, ce qui empêche le contexte de rendu WPF de s'afficher dans ce rectangle.

La meilleure option pour contourner ce problème nécessite .NET 3.5sp1 (au moins pour fonctionner de manière fiable). Vous pouvez contourner ce problème en créant une fenêtre d’arrière-plan entièrement transparente à 100% transparente et en la plaçant sur le contrôle d’hôte de votre Windows Forms. Vous dessinez ensuite dans celui-ci et il s'affichera correctement.

C'est un peu hacky, mais ça marche.

Autres conseils

J'ai eu le même problème et, après une recherche complète, j'ai également fini par utiliser la fenêtre transparente "superposition" au-dessus de WindowsFormsHost. Pour que votre fenêtre principale reste synchronisée avec la fenêtre de superposition, vous devez gérer les événements suivants:

Événement LocationChanged pour votre fenêtre principale et LayoutUpdated pour votre élément WindowsFormsHost. Ces deux gestionnaires d’événements doivent appeler une fonction qui déplace la fenêtre de superposition transparente au-dessus de la fenêtre WindowsFormsHost (SyncOverlayPosition () dans l’exemple ci-dessous).

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

La réponse acceptée fonctionne. Cependant, le seul problème avec cela est que la fenêtre transparente serait affichée sur ma fenêtre principale. Je devais également m'engager dans le mouvement pour m'assurer que tout restait synchronisé.

J'ai fait quelque chose de légèrement différent d'une fenêtre transparente. Cela a fonctionné dans mon cas, mais peut ne pas toujours fonctionner.

J'ai créé un contrôle utilisateur Windows Form. Je mets la zone de texte et le dessin au trait sur le contrôle utilisateur du formulaire Windows. Cela m'a ensuite permis de dessiner dessus et de l'afficher dans une application WPF à l'aide de WindowsFormsHost.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top