Domanda

Ecco il mio XAML

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

    </WindowsFormsHost>
</Grid>

Al caricamento del modulo eseguo il seguente metodo

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 linea si disegna solo quando commento la seguente riga.

this.winFormsHost.Child = oldSchoolTextbox;

Come posso tracciare una linea sul controllo WindowsFormsHost?

È stato utile?

Soluzione

C'è qualcosa che Microsoft ha chiamato " spazio aereo " ciò impedisce che ciò accada, almeno facilmente. Ecco la pagina di interoperabilità del WPF che descrive lo spazio aereo . [Ha un focus DX, ma la stessa cosa si applica, esattamente come indicato, a WindowsFormsHost.]

WindowsFormsHost (quando ha un figlio) crea un HWND separato, che impedisce al contesto di rendering WPF di essere visualizzato in quel rettangolo.

L'opzione migliore per ovviare a questo richiede .NET 3.5sp1 (almeno per funzionare in modo affidabile). Puoi aggirare il problema creando una finestra di sfondo completamente separata e trasparente al 100% e posizionandola sopra il controllo host dei moduli di Windows. Quindi ci attiri e verrà visualizzato correttamente.

È un po 'confuso, ma funziona.

Altri suggerimenti

Ho avuto lo stesso problema e dopo aver cercato dappertutto ho anche finito con la finestra trasparente 'overlay' in cima a WindowsFormsHost. Per mantenere la finestra principale sincronizzata con la finestra di overlay, devi gestire i seguenti eventi:

Evento LocationChanged per la tua MainWindow e Evento LayoutUpdated per l'elemento WindowsFormsHost. Entrambi questi gestori di eventi dovrebbero chiamare una funzione che sposta la finestra di overlay trasparente sopra la finestra di WindowsFormsHost (SyncOverlayPosition () nell'esempio seguente).

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 risposta accettata funziona. Tuttavia, l'unico problema è che la finestra trasparente verrà visualizzata sulla mia finestra principale. Ho anche dovuto agganciarmi al movimento per assicurarmi che tutto rimanesse sincronizzato.

Ho fatto qualcosa di leggermente diverso da una finestra trasparente. Nel mio caso ha funzionato, ma potrebbe non funzionare sempre.

Ho creato un controllo utente di Windows Form. Ho messo la casella di testo e il disegno sulla finestra sotto controllo utente. Questo mi ha quindi permesso di disegnarci sopra e visualizzarlo in un'applicazione WPF usando WindowsFormsHost.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top