Winforms Webbrowser neu laden eines angezeigten PDF Dokumentes

  • VB.NET
  • .NET (FX) 4.0

Es gibt 13 Antworten in diesem Thema. Der letzte Beitrag () ist von RodFromGermany.

    Winforms Webbrowser neu laden eines angezeigten PDF Dokumentes

    Hallo,
    Ich nutze in meiner Winforms Anwendung eine WebbrowserControl zur Anzeige von PDF-Dokumenten.
    Dies funktioniert soweit auch ganz gut. Bis auf einen speziellen Fall:

    Wenn ich ein Dokument in der Anzeige habe, und ich dieses dann neu laden lassen möchte, dann wird mir das Dokument nicht mehr angezeigt.
    Solange ich mit Webbrowser1.Navigate() zu einem anderen Dokument navigiere ist alles schick und wird sauber angezeigt. Wähle ich allerdings das selbe Dokument erneut zur Anzeige aus, welches schon geladen ist, dann klappt es nicht. Die Webbrowsercontrol ist dann einfach leer.

    Zur Lösung dieses Problems habe ich bereits versucht, zunächst zu "about:blank" zu navigieren. Auch dies half nichts.
    Bei der Recherche habe ich dann Sachen wie auf das DocumentCompleted Event warten und dann das PDF erst erneut laden gefunden. Aber auch das klappt irgendwie nicht...

    Hier mal ein Stück Code dazu.

    VB.NET-Quellcode

    1. Private Sub BSDocChanged(ByVal newURL As String)
    2. Try
    3. If Not (oldUrl = newURL) Then
    4. WebBrowser1.Navigate(newURL)
    5. Else
    6. WebBrowser1.Navigate("about:blank")
    7. WebBrowser1.Navigate(newURL)
    8. End If
    9. Catch ex As Exception
    10. MessageBox.Show(ex.ToString)
    11. End Try
    12. End Sub


    Hat jemand eine Idee, wie man dieses Problem mit der PDF Anzeige in der Webbrowsercontrol lösen könnte?

    MfG
    shoddi
    @shoddi Wenn Du das (oder so ein) Dokument mal posten kannst, könnten wir versuchen, den Effekt nachzustellen.
    Was mit ziemlicher Sicherheit funktionieren dürfte:
    Wenn Du vor dem Navigieren den WebBrowser disposest und neu instanziierst.
    Allerdings ist das mit Kanonen auf Spatzen geschossen.

    VB.NET-Quellcode

    1. WebBrowser1.Dispose()
    2. WebBrowser1 = New WebBrowser
    3. WebBrowser1.xx = yy ' alle relevanten Properties setzen: Dock, Anchor und solch
    4. Me.Controls.Add(WebBrowser1) ' dem richtigen Parent zuordnen
    5. WebBrowser1.Navigate(...)
    Den Code zum Setzen der Properties holst Du Dir aus der FormX.Designer.vb aus der Prozedur InitializeComponents().
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    shoddi schrieb:

    Der Effekt tritt auf
    Ich hab mal folgendes Projekt gemacht:

    VB.NET-Quellcode

    1. Public Class Form1
    2. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    3. WebBrowser1.Navigate("C:\Temp\Auflage1.pdf")
    4. End Sub
    5. Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
    6. WebBrowser1.Navigate("C:\Temp\Auflage2.pdf")
    7. End Sub
    8. End Class
    Da kann ich auf die Button drücken wie ich will, es wird alles korrekt angezeigt.
    Microsoft Visual Studio Ultimate 2013
    sowohl Framework 2.0 als auch 4.5.
    Wie sieht Dein Code aus?
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Also, Ich benutze Visual Studio 2010 Professional SP1 und Framework 4.0.
    Im Prinzip habe ich ne Bindingsource, bei der ich im CurrentChanged-Event die Sub zur Navigation aufrufe:

    VB.NET-Quellcode

    1. Private Sub BsEkAB_CurrentChanged(sender As System.Object, e As System.EventArgs) Handles BsEkAB.CurrentChanged
    2. Dim current As BindingSource = CType(sender, BindingSource)
    3. Try
    4. If current.Count < 1 Then
    5. BSDocChanged("")
    6. Else
    7. BSDocChanged(current.Current("ekab_pfad_datei"))
    8. End If
    9. Catch ex As Exception
    10. MessageBox.Show(ex.ToString)
    11. End Try
    12. End Sub


    Dort wird dann die folgende Sub aufgerufen:

    VB.NET-Quellcode

    1. Private Sub BSDocChanged(ByVal newURL As String)
    2. Try
    3. Dim oldUrl As String = WebBrowser1.Url.LocalPath & WebBrowser1.Url.Fragment
    4. Dim newUrltmp As String = newURL
    5.  
    6. If (newURL = "") Or (IsNothing(newURL)) Or (newURL = "about:blank") Then
    7. newURL = "about:blank"
    8. Else
    9. newURL = newURL & "#toolbar=0&navpanes=0&view=FitV"
    10. End If
    11. If Not (oldUrl = newURL) Then
    12. WebBrowser1.Navigate(newURL)
    13. Else
    14. WebBrowser1.Navigate("about:blank")
    15. WebBrowser1.Navigate(newURL)
    16. End If
    17. Catch ex As Exception
    18. MessageBox.Show(ex.ToString)
    19. End Try
    20. End Sub
    @shoddi Wo kommt denn das BindingSource-Event her?
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    @RodFromGermany Im Prinzip habe ich ein Datagridview, das an die Bindingsource gebunden ist. In dem Datagridview kann man dann das Dokument anwählen, welches man angezeigt haben möchte. Dadurch wird dann bei Wechsel der Auswahl das CurrentChanged-Event ausgelöst. Andererseits habe ich auch noch die Möglichkeit eingebaut, dass man nach bestimmten Dingen filtern kann. Dabei wird dann ein BindingSource Filter gesetzt. Dort werden dann auch CurrentChanged-Events ausgelöst.
    @shoddi Kannst Du vielleicht das ganze Projekt posten, damit ich das nachvollziehen kann?
    Projektmappe bereinigen (keine obj und bin-Ordner), zippen und als Datei anhängen.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    @RodFromGermany Das ganze Projekt zu posten ist mir leider nicht möglich, allerdings habe ich inzwischen herausgefunden, woran es zu liegen scheint. Als PDF Viewer nutze ich den Acrobat Reader DC, welcher dann ja auch in der Webbrowsercontrol genutzt wird. Um nur das reine PDF-Dokument anzuzeigen, ohne Toolbars, Thumbnails etc. füge ich beim navigieren noch "#toolbar=0&navpanes=0&view=FitV" an das Navigationsziel an. Dies scheint das ganze auszulösen. Ohne diese zusätzlichen Parameter wird artig das PDF-Dokument neu geladen, allerdings dann mit Toolbars etc. Sobald dann einer der 3 Parameter hinzukommt, funktioniert die Navigation zum bereits angezeigten Dokument nicht mehr und der Webbrowser bleibt grau.

    Da ich aber nur das "reine" Dokument anzeigen lassen möchte, ist das weglassen dieser Parameter keine Option für mich.

    shoddi schrieb:

    Das ganze Projekt zu posten
    dann mach ein kleines neues Projekt, das den Effekt reproduziert.
    Manchmal hilft dies, den Zieleffekt herauszukristallisieren.
    Ich weiß jetzt nicht, wo man eine Beschreibung dieser Parameter her bekommen könnte, allerdings kannst Du mögliche Kombinationen aus Deinem Browser rauskopieren. Vielleicht nimmst Du da auch mal einen anderen (InternetExplorer, FireFox, Opera, ...) um deren "Sichtweise" zu untersuchen.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    @shoddi OK, ich habs gesehen.
    Erst mal, was ich schon oben gesagt habe, ohne die Appendizes funktioniert das.
    Als kleines Arbeitsdrumherum kannst Du Dir ja merken, wohin zuletzt navigiert wurde, und wenn das Ziel dasselbe ist, machst Du einfach nix:

    VB.NET-Quellcode

    1. Public Class Form1
    2. Private LastTarget As String
    3. Private Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Button1.Click
    4. Dim Target = "C:\Temp\Dokument1.pdf#toolbar=0&navpanes=0&view=FitV"
    5. If LastTarget <> Target Then
    6. WebBrowser1.Navigate(Target)
    7. LastTarget = Target
    8. End If
    9. End Sub
    10. Private Sub Button2_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Button2.Click
    11. Dim Target = "C:\Temp\Dokument2.pdf#toolbar=0&navpanes=0&view=FitV"
    12. If LastTarget <> Target Then
    13. WebBrowser1.Navigate(Target)
    14. LastTarget = Target
    15. End If
    16. End Sub
    17. End Class
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    shoddi schrieb:

    oder die Variante mit dem disposen des Webbrowsers
    Das würde ich jetzt zurückziehen und die letztre als die elegantere betrachten.
    Ein Arbeitsdrumherum sind sie beide.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!