2009-09-05 10 views
11

this question (click me!)のおかげで、WebBrowserという私のViewModelに正しくバインドされたSourceというプロパティがあります。私の戻る]ボタンや[進む]ボタンのIsEnabledプロパティが正しくWebBrowserCanGoBackCanGoForwardプロパティにバインドするには、GetWPFでWebブラウザーコントロールを使用するMVVMに優しい方法はありますか?

  1. 今私は2つの目標を達成したいと思います。

  2. 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="&lt; Back" /> 

<Button 
    Style="{StaticResource Button_Style}" 
    Grid.Column="4" 
    IsEnabled="{Binding ElementName=_instructionsWebBrowser, Path=CanGoForward}" 
    Command="{Binding GoForwardCommand}" 
    Content="Forward &gt;" /> 

私は問題がCanGoBackCanGoForwardは、依存関係プロパティではありません(と実装していないということであるかなり確信していますINotifyChanged)、私はそれを回避する方法についてはあまりよく分かりません。

質問:

  1. (私はSourceで行ったように)添付プロパティをフックアップまたはCanGoBackCanGoForwardバインディングが仕事を得るために似たような方法はありますか?

  2. GoBackCommandGoForwardCommandは、コードビハインドとViewModelから独立しているため、マークアップで宣言できますか?

答えて

4

は、私は私のバインド可能なウェブブラウザのラッパーで、これを使用する:私はDependencyPropertiesを公開し、実際のブラウザ要素のメソッドを呼び出したFrameworkElementとしての私のバインド可能なウェブブラウザを作成し

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)); 

注ので、私はに関するCommandBindingsを設定することができますそれ。

このようにして、ビュー内のデフォルトのナビゲーションコマンドを使用できます。 使用ハンドラは以下のとおりです。

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); 
} 
+0

@Botz、ありがとうございます。実際に 'FrameworkElement'クラスをどのように設定するかについては、少し曇っています。フィールド 'webBrowser'を持っていると仮定しますが、実際にそれをどのように表示させるのですか?私は 'UserControl'をビルドし、実際に' WebBrowser'を 'Grid'に配置する必要があると考えていました。あなたは 'FrameworkElement'を継承するクラスでこれをどのように扱いますか?ありがとう。 – devuxer

+0

実際にはUserControlは必要ありませんが、正しく設定している限り、FrameworkElementは問題ありません。私の実装は最良ではないかもしれませんが、見たい場合はコントロールはhttp://pastebin.com/m492dbd3fにあります(BrowserViewModelについて不思議なら、コントロールのプロパティが実際にバインドされているViewModelですあなたが既に独自のViewModelを持っていると確信しています) – Botz3000

+0

// btw FrameworkElementから派生している場合は、AddVisualChildとAddLogicalChildを呼び出して実際にWebBrowserやその他のものを呼び出すことができます – Botz3000

0

あなたの質問は正確にあなたが任意のコードビハインド持つことが許可されていませんMVVMパターンを実装するために、それを暗示しているようです。しかし、おそらくあなたのビューにいくつかのコードビハインドを追加することは、あなたのビューモデルにそれを接続することをはるかに簡単になります。ビューに依存プロパティーを追加して、INotifyPropertyChangedイベントをlistenすることができます。

4

この質問に遭遇し、完全な解決策が必要な人は、ここをクリックしてください。このスレッドで作られたすべての提案とリンクされたスレッド(およびそのスレッドにリンクされているもの)を組み合わせています。

XAML: http://pastebin.com/aED9pvW8

C#クラス: http://pastebin.com/n6cW9ZBB

例XAMLの使用法: http://pastebin.com/JpuNrFq8

注:例では、あなたのビューがブラウザにソースURLを提供ViewModelにに結合すると仮定し。デモのために、バック、フォワード、リフレッシュボタンとアドレスバーを備えた非常に初歩的なナビゲーションバーが用意されています。

お楽しみください。私はそれらのpastebinの期限を決して決して設定していないので、pastebinが存在する限り利用できるはずです。

+0

非常に良い、ありがとう。私は_SkipSourceChangeが何のためにあるのだろうかと思っていましたか? – Peter

関連する問題