Come passare un componente Form ad un metodo di un modulo ?

di il
7 risposte

Come passare un componente Form ad un metodo di un modulo ?

Nella FormMain ho il componente wwMap di tipo CefSharp.WinForms.ChromiumWebBrowser.

Da FormMain posso utilizzare il metodo: wwMap.ExecuteScriptAsync .
E qua tutto ok.

Però se creo un modulo con la seguente situazione:
Module mMapInit
Public Sub AirspaceA(ByRef map As CefSharp.WinForms.ChromiumWebBrowser)
        map. TADAA non mi fa vedere il metodo ExecuteScriptAsync
Come dovrei passare il componente wwMap alla subroutine del modulo ?

Grazie.

7 Risposte

  • Re: Come passare un componente Form ad un metodo di un modulo ?

    jockerfox ha scritto:


    Come dovrei passare il componente wwMap alla subroutine del modulo ?
    Intanto, non vedo perché usare ByRef invece di ByVal.

    Inoltre, il metodo che cerchi di chiamare è asincrono, pertanto andrebbe chiamato all'interno di un metodo anch'esso asincrono: se non sai di cosa sto parlando, devi approfondire questo aspetto.

    Ciao!
  • Re: Come passare un componente Form ad un metodo di un modulo ?

    Ciao Marco.
    Per quanto la chiamata asincrona, la documentazione recita:
    Execute some Javascript code in the context of this WebBrowser. As the method name implies, the script will be executed asynchronously, and the method therefore returns before the script has actually been executed.
    Per cui non vedo il motivo di creare una funzione Async.

    Per quanto riguarda ByRef invece di ByVal, è stato solo per disperazione. Avevo pensato <<provo a passarlo come Riferimento.. fosse magari l'errore qua..>>

    MA HO RISOLTO, mea culpa, con Imports CefSharp nel modulo..
    Tutto funziona, lo script Java funziona.. Insomma tutto ok.

    PERO' una ultima finezza su questo modulo.
    Per evitare di passare tutte le volte il componente CEF alla funzione del modulo, mi sarebbe più comodo dichiarare il componente CEF nel modulo stesso:

    Imports CefSharp
    Module mMapInit
    Private wwMap As CefSharp.WinForms.ChromiumWebBrowser = My.Forms.FormMain.wwMap

    per poi lavorarci nelle Sub/Function del modulo.

    Ma purtroppo ho il seguente errore:

    System.Exception: 'IBrowser instance is null. Browser has likely not finished initializing or is in the process of disposing.'

    Il componete che ho su FormMain è sicuramente istanziato..
    << infatti se il chiamante passa wwMap alla funzione: lo script è eseguito correttamente. Per cui è istanziato ! >>
    Sicuramente quello che mi va a leggere non è certo quello del FormMain. Strano.. gli ho detto: My.Forms.FormMain.wwMap

    Cosa sbaglio ?

    Grazie.
  • Re: Come passare un componente Form ad un metodo di un modulo ?

    jockerfox ha scritto:


    Per quanto la chiamata asincrona, la documentazione recita:
    Execute some Javascript code in the context of this WebBrowser. As the method name implies, the script will be executed asynchronously, and the method therefore returns before the script has actually been executed.
    Per cui non vedo il motivo di creare una funzione Async.
    Non vedo il nesso. Quanto hai citato della documentazione indica espressamente che l'esecuzione è asincrona, e questo è suggerito anche dal nome del metodo.

    La creazione di una funzione Async è coerente con il fatto che qualunque funzione chiami metodi asincroni sarà anch'essa asincrona, quindi è bene marcarla come tale; in alternativa, devi gestire il valore di ritorno della funzione asincrona (che è un Task) e metterti in attesa del suo completamento, ossia trasformare il processo in "sincrono".

    jockerfox ha scritto:


    Per quanto riguarda ByRef invece di ByVal, è stato solo per disperazione.
    Non si usano parole chiave e costrutti "per disperazione": si approfondisce il loro significato e ciò a cui servono, una volta chiarito quello si usano solo se ha senso farlo. Non si va a caso.

    jockerfox ha scritto:


    Per evitare di passare tutte le volte il componente CEF alla funzione del modulo, mi sarebbe più comodo dichiarare il componente CEF nel modulo stesso [...]
    Innanzitutto, abbandonerei lo strumento del "modulo VB": siamo in un contesto OOP grazie alla piattaforma .NET, quindi meglio parlare di classi e oggetti.

    Detto questo, se lo dichiari nel modulo, avrebbe senso che tu lo "istanziassi" (creassi) anche nel modulo, ma se proprio vuoi creare un modulo che gestisca una serie di funzioni basate su un componente esterno che non vuoi passare ad ogni chiamata, allora devi prevedere nel modulo la possibilità di passare quel riferimento al componente su cui vuoi lavorare.

    jockerfox ha scritto:


    Private wwMap As CefSharp.WinForms.ChromiumWebBrowser = My.Forms.FormMain.wwMap
    Questo approccio non va bene: non deve essere il modulo ad andarsi a recuperare il componente, altrimenti non puoi nemmeno riusarlo in altri contesti dove magari quel Form non è presente o dove il componente è situato altrove. Al massimo, lascia quel campo non inizializzato e prevedi una procedura per prendere un riferimento a un browser e mettere il suo valore nel campo.

    Eviterei anche questo tipo di scrittura: My.Forms.FormMain.wwMap. Stai usando un escamotage di VB (che io giudico terribile) dove si può usare il nome della classe del Form per far creare automaticamente una istanza della stessa e lavorare su quella. Il rischio qui è che ti venga creata dietro le quinte una nuova finestra FormMain e che il componente su cui vai a lavorare sia diverso dall'effettiva finestra principale dell'applicazione, che viene istanziata con new FormMain() in fase di avvio dell'applicazione.

    jockerfox ha scritto:


    Ma purtroppo ho il seguente errore:
    System.Exception: 'IBrowser instance is null. Browser has likely not finished initializing or is in the process of disposing.'
    Il componete che ho su FormMain è sicuramente istanziato..
    << infatti se il chiamante passa wwMap alla funzione: lo script è eseguito correttamente. Per cui è istanziato ! >>
    Sicuramente quello che mi va a leggere non è certo quello del FormMain. Strano.. gli ho detto: My.Forms.FormMain.wwMap
    Appunto: vedi quello che ho scritto sopra.

    jockerfox ha scritto:


    Cosa sbaglio ?
    Non ti documenti abbastanza: devi studiare la OOP, come minimo, e non andare a tentoni nell'uso di parole chiave sperando che magicamente risolvano un problema di cui non comprendi le cause reali.

    Ci sarebbero tante altre cose, ma mi fermo qui perché il tempo è infinito e i corsi di programmazione sono per i miei clienti.

    Ciao!
  • Re: Come passare un componente Form ad un metodo di un modulo ?

    Non so se può esserti utile, ma eccoti la routine che uso io per chiamare il javascript
    
    Private WithEvents cwb As ChromiumWebBrowser
    
        Private Function ExecuteScript(JavaScript As String) As JavascriptResponse
    
            Do Until cwb.IsBrowserInitialized
                Application.DoEvents()
                Threading.Thread.Sleep(50)
            Loop
    
            Dim Jres As JavascriptResponse = Nothing
            cwb.GetMainFrame.EvaluateScriptAsync(JavaScript).ContinueWith(
                Sub(u)
                    Jres = u.Result
                End Sub
            )
    
            Do Until Jres IsNot Nothing
                Application.DoEvents()
                Threading.Thread.Sleep(50)
            Loop
            Return Jres
    
        End Function
    
    e poi, ad esempio:
    
    Dim Jres = ExecuteScript("(function(){ if (document.getElementById('MyButton') == null) return 0; else return 1; })()")
    
    e poi analizzo Jres
  • Re: Come passare un componente Form ad un metodo di un modulo ?

    SirJo ha scritto:


    Non so se può esserti utile, ma eccoti la routine che uso io per chiamare il javascript [...]
    
            Dim Jres As JavascriptResponse = Nothing
            cwb.GetMainFrame.EvaluateScriptAsync(JavaScript).ContinueWith(
                Sub(u)
                    Jres = u.Result
                End Sub
            )
    
            Do Until Jres IsNot Nothing
                Application.DoEvents()
                Threading.Thread.Sleep(50)
            Loop
    
    Funzionerà pure, ma se fossi il santo creatore dei Task e delle classi di Asynchronous Programming in .NET, morirei solo per rivoltarmi nella tomba.
  • Re: Come passare un componente Form ad un metodo di un modulo ?

    Eh, lo sapevo Marco che mi cazziavi, ed hai anche perfettamente ragione

    In realtà io ci ho fatto solo qualche piccola modifica, il codice principale lo avevo trovato nonmiricordodove su internet
  • Re: Come passare un componente Form ad un metodo di un modulo ?

    SirJo ha scritto:


    In realtà io ci ho fatto solo qualche piccola modifica, il codice principale lo avevo trovato nonmiricordodove su internet
    Non è che tutto quello che si trova su Internet sia da prendere come buono, ad ogni modo direi che l'importante è risolvere, o quando si "sgarra" sapere quello che si sta facendo.

    In caso contrario, i problemi sono dietro l'angolo...
Devi accedere o registrarti per scrivere nel forum
7 risposte