2009-11-19 11 views
5

Ho un problema frustrante. Ecco una versione semplificata di quello che sto facendo:Il controllo WebBrowser WPF non entra in modalità progettazione quando viene modificata la proprietà del documento

Un controllo utente in C# contiene una barra degli strumenti e un oggetto WebBrowser incorporato. La barra degli strumenti contiene un pulsante "Modifica", che quando viene cliccato imposta il controllo del browser in modalità progettazione. Un altro pulsante, "Annulla", disattiva la modalità di progettazione.

Pseudocodice (molto semplificata):

public void SetDesignMode(bool dm) { 
    IHTMLDocument2 doc = webBrowser.Document as IHTMLDocument2; 
    if (dm) doc.designMode = "On"; 
    else doc.designMode = "Off"; 
    _designMode = dm; 
    ReloadDocument(); // setting designmode clears the document element, so it must be reloaded 
} 

public void OnLoadCompleted() { 
    IHTMLDocument2 doc = webBrowser.Document as IHTMLDocument2; 
    if (!_documentLoaded) { 
    if (_designMode) doc.designMode = "On"; 
    else doc.designMode = "Off"; 
    ReloadDocument(); 
    _documentLoaded = true; 
    } 
} 

public void ReloadDocument() { 
    _documentLoaded = false; 
    // code that navigates to the document 
} 

Il problema: Se clicco sulla pagina web visualizzata, e poi sul pulsante "Modifica", il controllo WebBrowser non diventerà modificabile . Il puntatore del mouse durante l'acquisizione di immagini/collegamenti mostra i puntatori del mouse di navigazione del browser Web, non quelli di modifica. Se clicco nel testo, il segno di omissione non verrà visualizzato.

Il debug rivela che la proprietà designMode sul documento è effettivamente impostata su "On" in questa situazione, ma il controllo si comporta come se fosse impostato su "Off".

Se Non click nella pagina web prima di fare clic sul pulsante "Modifica", tutto funziona come previsto.

Elaborazione: Se si fa clic sul pulsante "Annulla" quando il controllo è in modalità di progettazione, ho la (dis) comportamento corrispondente, se il documento è stato cliccato in

Semplicemente cliccando su ". Modifica ", quindi" Annulla ", quindi" Modifica "ecc. Senza mai fare clic sul documento funziona correttamente (il test del mouseover mostra i puntatori del mouse corretti, e ottengo la navigazione o la modifica del link in base alla modalità di progettazione se faccio clic su un collegamento in il documento visualizzato).

Ho provato varie tecniche per assicurarsi che un altro controllo ottenga lo stato attivo prima di modificare la proprietà designMode, ma non fa alcuna differenza. Ho cercato MSDN e metà di Internet conosciuto e non ho trovato alcuna menzione di questo tipo di problema. Capovolgere la proprietà designMode come questo sembra essere abbastanza insolito.

Un altro bocconcino di informazioni: sto configurando gli eventi del documento consigliando il documento con un sink implementato dal controllo us. Dubito che questo dovrebbe avere alcuna incidenza sul problema, ma l'ho incluso qui per il gusto di essere completo. Aggiornamento: La disattivazione di questo non modifica nulla riguardo al problema.

Qualcuno riconosce questo problema?

Aggiornamento: Ho risolto il problema ricreando il controllo del browser Web in SetDesignMode(). È una brutta soluzione, ma funziona e sembra davvero ok. Sono molto interessato a qualsiasi feedback su questo problema, però. Credo che sia un bug in MSHTML.

risposta

8

Non sono abbastanza sicuro se abbiamo avuto esattamente lo stesso problema, ma suppongo che la mia soluzione dovrebbe funzionare anche per voi.

Il problema di base sembra essere che x64 ripristina l'attributo designMode, come indicato in this article. Nel mio caso, l'ho impostato su "On" dopo aver istanziato il browser, ma nell'evento DocumentCompleted, era di nuovo "Inherit". Impostandolo su "On" in DocumentCompleted lo rende modificabile, ma cancella il documento. L'impostazione di DocumentText ricomincia di nuovo l'intero ciclo di distruzione.

Così una soluzione che ho trovato è stato quello non fissare DocumentText, invece ho creato un documento vuoto, quindi impostare del corpo (che a questo punto non è più nullo) InnerHtml proprietà:

doc.designMode = "On"; // enable editing 

// designMode change resets the document, create it anew 
webBrowser1.Document.Write("<html><body></body></html>") 
webBrowser1.Document.Body.InnerHtml = "myDocumentText" 

Ovviamente, questo funziona solo se hai il testo pronto e non se stai navigando verso un URL. Tuttavia, c'è un'altra soluzione che ha funzionato per me, che sembra più facile e più sicura. L'ho trovato in this answer di LaughingJohn. Immagino che la prima riga dipenda dalla tua applicazione, tu avevi l'IHTMLDocument direttamente in webBrowser1.Document.

doc = webBrowser1.Document.DomDocument as IHTMLDocument2; 
if (doc != null && doc.body != null) 
    ((HtmlBody)doc.body).contentEditable = "true"; 
+0

Entrambi i metodi funzionano, grazie. Però; Il primo metodo in qualche modo ha messo il mio "Annulla" (Ctrl-Z/ExecCommand ("Annulla" ...)) fuori azione. Sul secondo metodo, le modifiche non si riflettono su webBrowser.DocumentText per qualche motivo. Sono stato in grado di estrarlo tramite webBrowser.Dcoument.Body.InnerHtml e ho risolto il problema. – Natan

0

Mi sembra che lo WebBrowser ottenga lo stato attivo quando si fa clic su di esso e in qualche modo si trattiene. Prova questo: fai clic su WebBrowser, quindi premi il tasto Tab sulla tastiera (quale dovrebbe spostare lo stato attivo su WebBrowser) e quindi vedere se è possibile fare clic sui pulsanti.

Se possibile, quindi provare ad associare un gestore all'evento Button.MouseEnter e chiamare ((Button)sender).Foucs() al suo interno per mettere a fuoco il pulsante a livello di programmazione.