Есть ли MVVM-дружественный способ использовать элемент управления WebBrowser в WPF?
спасибо этот вопрос (нажми на меня!), я Source
свойство my WebBrowser
правильно привязка к моей ViewModel.
теперь я хотел бы достичь еще двух целей:
- скачать
IsEnabled
свойство моих кнопок Назад и вперед для правильной привязки кCanGoBack
иCanGoForward
свойстваWebBrowser
. - выяснить, как вызвать
GoForward()
иGoBack()
методы без прибегать к Код-за и без ViewModel должен знать оWebBrowser
.
на данный момент у меня есть следующая (нерабочая) разметка XAML:
<WebBrowser
x:Name="_instructionsWebBrowser"
x:FieldModifier="private"
clwm:WebBrowserUtility.AttachedSource="{Binding InstructionsSource}" />
<Button
Style="{StaticResource Button_Style}"
Grid.Column="2"
IsEnabled="{Binding ElementName=_instructionsWebBrowser, Path=CanGoBack}"
Command="{Binding GoBackCommand}"
Content="< Back" />
<Button
Style="{StaticResource Button_Style}"
Grid.Column="4"
IsEnabled="{Binding ElementName=_instructionsWebBrowser, Path=CanGoForward}"
Command="{Binding GoForwardCommand}"
Content="Forward >" />
я уверен, что проблема в том, что CanGoBack
и CanGoForward
не являются свойствами зависимостей (и не реализовать INotifyChanged
), но я не совсем уверен, как обойти это.
вопросы:
есть ли способ подключить вложенные свойства (как я сделал с
Source
) или что-то похожее, чтобы получитьCanGoBack
иCanGoForward
привязки к работе?как писать
GoBackCommand
иGoForwardCommand
таким образом, они не зависят от кода и ViewModel и могут быть объявлены в разметке?
3 ответов
я использовал это в моей bindable оболочке webbrowser:
CommandBindings.Add(new CommandBinding(NavigationCommands.BrowseBack, BrowseBack, CanBrowseBack));
CommandBindings.Add(new CommandBinding(NavigationCommands.BrowseForward, BrowseForward, CanBrowseForward));
CommandBindings.Add(new CommandBinding(NavigationCommands.BrowseHome, GoHome, TrueCanExecute));
CommandBindings.Add(new CommandBinding(NavigationCommands.Refresh, Refresh, TrueCanExecute));
CommandBindings.Add(new CommandBinding(NavigationCommands.BrowseStop, Stop, TrueCanExecute));
обратите внимание, что я создал свой bindable webbrowser как FrameworkElement, который предоставляет DependencyProperties и вызывает методы на фактическом элементе браузера, поэтому я могу установить CommandBindings на нем.
таким образом, Вы можете использовать NavigationCommands по умолчанию в своем представлении. Используемые обработчики:
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);
}
для тех, кто сталкивается с этим вопросом и хочет полного решения, вот он. Он сочетает в себе все предложения, сделанные в этом потоке, и связанные потоки (и другие ссылки).
в XAML: http://pastebin.com/aED9pvW8
C# - класс : http://pastebin.com/n6cW9ZBB
пример использования XAML : http://pastebin.com/JpuNrFq8
Примечание: пример предполагает, что ваше представление привязывается к ViewModel это предоставляет исходный URL-адрес браузера. Очень рудиментарная панель навигации с Назад, Вперед, и кнопки обновления и адресной строки предоставляется только для демонстрации.
наслаждайтесь. Я установил срок годности этих пастебинов на никогда, поэтому они должны быть доступны до тех пор, пока существует пастебин.
ваш вопрос, похоже, подразумевает, что для правильной реализации шаблона MVVM вам не разрешено иметь какой-либо код. Но, возможно, добавление некоторого кода в ваше представление значительно упростит его подключение к вашей модели представления. Вы можете добавить свойства зависимостей в представление и позволить ему слушать INotifyPropertyChanged
событий.