2009-09-05 4 views
11

덕분에 this question (click me!) 덕분에 WebBrowserSource 속성이 내 ViewModel에 올바르게 바인딩되었습니다.WPF에서 WebBrowser 컨트롤을 사용하는 MVVM 친화적 인 방법이 있습니까?

지금은 두 개 더 목표를 달성하고 싶습니다 :

  1. 제대로 WebBrowserCanGoBackCanGoForward 속성에 바인딩 내 뒤로 및 앞으로 버튼의 IsEnabled 속성을 가져옵니다.
  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을 설정할 수 있습니다 그것.

이렇게하면보기에서 기본 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); 
} 
+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 청취하도록 할 수 있습니다.

4

이 질문에 도달하고 완벽한 해결책을 원하는 사람은 누구나 들어 있습니다. 이 스레드에서 만들어진 모든 제안과 링크 된 스레드 (및 그 스레드에 링크 된 다른 스레드)를 결합합니다.

XAML : http://pastebin.com/aED9pvW8

C# 클래스 : http://pastebin.com/n6cW9ZBB

예 XAML 사용 : http://pastebin.com/JpuNrFq8

참고 :이 예는보기가 브라우저에 소스 URL을 제공하는 뷰 모델에 결합 가정 . 데모 용으로는 뒤로, 앞으로 및 새로 고침 버튼과 주소 표시 줄이있는 매우 기본적인 탐색 모음이 제공됩니다.

즐기십시오. 그 pastebin의 만료 시간을 절대로 설정하지 않았으므로 pastebin이 존재하는 한 사용할 수 있어야합니다.

+0

정말 고마워. 고마워. _SkipSourceChange가 무엇인지 궁금합니다. – Peter

관련 문제