11
votes

Existe-t-il un moyen convivial MVVM d'utiliser le contrôle WebBrowser dans WPF?

Merci à Cette question (cliquez sur moi!) , j'ai la propriété Source de mon < Code> WebBrowser Binding correctement à ma viewModel.

Maintenant, je voudrais réaliser deux autres objectifs:

  1. Obtenez la propriété isenabled de mes boutons de mon dos et d'avant pour se lier correctement au CANGOBACK et CANGOFORWARD Propriétés du WebBrowser / code>.
  2. Mouvez comment appeler le goforward () et goback () Méthodes sans recourir au code-derrière et sans la viewModel qui doit connaître le WebBrowser .

    J'ai le marquage XAML suivant (non fonctionnel) pour le moment: xxx

    Je suis sûr que le problème est que cangoback et cangoforward ne sont pas des propriétés de dépendance (et ne mettez pas d'implémenter inotifychanged ), mais je ne suis pas tout à fait sûr de savoir comment se déplacer.

    questions:

    1. existe-t-il un moyen de connecter les propriétés attachées (comme je l'ai fait avec source ) ou quelque chose de similaire pour obtenir le cangoback et cangoforward Les liaisons au travail?

    2. Comment écrire le gobackcommand et goforwardcommand afin qu'ils soient indépendants du code-derrière et de la vieilleModel et peuvent être déclarés dans le balisage? < / li>


0 commentaires

3 Réponses :


4
votes

J'ai utilisé cela dans mon wrapper WebBrowser liable:

private void CanBrowseBack(object sender, CanExecuteRoutedEventArgs e) {
    e.CanExecute = webBrowser.CanGoBack;
}

private void BrowseBack(object sender, ExecutedRoutedEventArgs e) {
    webBrowser.GoBack();
}

private void CanBrowseForward(object sender, CanExecuteRoutedEventArgs e) {
    e.CanExecute = webBrowser.CanGoForward;
}

private void BrowseForward(object sender, ExecutedRoutedEventArgs e) {
    webBrowser.GoForward();
}

private void TrueCanExecute(object sender, CanExecuteRoutedEventArgs e) { e.CanExecute = true; }

private void Refresh(object sender, ExecutedRoutedEventArgs e) {
    try { webBrowser.Refresh(); }
    catch (Exception ex) { PmsLog.LogException(ex, true); }
}

private void Stop(object sender, ExecutedRoutedEventArgs e) {
    mshtml.IHTMLDocument2 doc = WebBrowser.Document as mshtml.IHTMLDocument2;
    if (doc != null)
        doc.execCommand("Stop", true, null);
}
private void GoHome(object sender, ExecutedRoutedEventArgs e) {
    Source = new Uri(Home);
}


9 commentaires

@Botz, merci. Je suis un peu brumeux sur la façon dont vous avez réellement configuré votre classe Cadra FrameworkElement. Je suppose que vous avez un champ webbrowser , mais comment l'obtenez-vous réellement à afficher? Je pensais que j'aurais besoin de construire un usercontrol et placez-la réellement le webbrowser in, dites, un grille sur le contrôle. Comment gérez-vous cela avec une classe qui hérite FrameworkElement ? Merci.


Vous n'avez réellement besoin d'un UserControl, un frameworkElement est tout aussi bien que vous le configurez correctement. Ma mise en œuvre pourrait ne pas être la meilleure, mais si vous souhaitez avoir un look, le contrôle peut être trouvé ici: Pastebin.com/ M492DBD3F (Si vous vous demandez à propos de BrowserviewModel, c'est la viewModel Les propriétés de la commande sont en réalité liées, je suis sûr que vous avez déjà votre propre point de vue) cependant)


// BTW Si vous découlez de l'établissement, vous pouvez appeler AddVisualChild et AddLogicalChild pour mettre le webbrowser ou quoi que ce soit d'autre à l'intérieur de celui-ci.


@Botz, ahh, sympa, merci. Cela fonctionne dans ma fenêtre en ce moment. J'ai juste besoin d'un indice sur la façon de se lier à la navigationCommands.browseback. J'ai essayé Command = "{élément de liaisonName = _instrucancewebrowser, chemin = NavigationCommands.browseforward}" et Commande = "{Navigation NavigationCommands.browseforward}" Jusqu'ici chance. Merci encore!


@Botz, j'ai aussi essayé simplement commande = "navigationcommands.browseforward" , mais cela ne fonctionne pas non plus.


En fait, ce sont des commandes intégrées. Ils travaillent n'importe où dans votre application et sont liés de manière dynamique aux liaisons qui sont en vigueur pour l'élément actuellement en mise au point. Cela signifie également que différents contrôles peuvent chacun mettre en œuvre cette commande par elle-même et, selon laquelle on a l'accent, cette mise en œuvre est utilisée. Il suffit de les utiliser comme ceci: commande = "navigationcommands.browseforward" pour des éléments tels que Menuitems, même le texte est défini automatiquement simplement en le faisant.


Oh! Ouais, une chose était manquante. CommandTarget = "{élément de liaisonName = _instrucancewebrowser}"


Oui! ça fonctionne parfaitement maintenant. Merci pour votre aide :)


@ Botz3000: Souhaitez-vous laisser tomber le contrôle sur Pastebin pendant quelques jours, merci.



0
votes

Votre question semble impliquer que, afin de mettre en œuvre correctement un modèle MVVM, vous n'êtes pas autorisé à avoir de code-indicatif. Mais peut-être ajouter que certains code-derrière à votre vue vous permettront beaucoup plus facile de le connecter avec votre modèle de vue. Vous pouvez ajouter des propriétés de dépendance à la vue et la laisser écouter pour inotifypropertychanged événements.


0 commentaires

5
votes

Pour quiconque appartient à cette question et veut une solution complète, c'est ici. Il combine toutes les suggestions faites dans ce fil et les threads liés (et d'autres personnes liées à).

xaml: http://pastebin.com/aed9PVW8

C # Classe: http://pastebin.com/n6cw9zbb

Exemple d'utilisation XAML: http://pastebin.com/jpunrfq8

Remarque: l'exemple suppose que votre vue se lie à une vue de vue qui fournit l'URL source au navigateur. Une barre de navigation très rudimentaire avec des boutons de dos, d'avant et de rafraîchissement et une barre d'adresse est fournie juste à la manifestation.

profiter. J'ai défini l'expiration sur ces pastebin pour jamais, ils devraient donc être disponibles aussi longtemps que la pâtebine existe.


1 commentaires

Très gentil merci. Je me demandais ce que le _skipsourcechange est là pour?