0

この SO questionで説明されているものと同様の問題が発生しています。推奨される解決策は、提示したいページ (PDF) ごとに新しい WebBrowser コントロールを作成することです (古い WebBrowser コントロールを上書きします)。MVVM でそのような新しいコントロールを作成する正しい方法は何ですか? ビューの実装について VM を認識させないようにしています。

4

3 に答える 3

1

VM が知る必要があるのはなぜですか? ビューを適切なイベントにフックして (必要に応じてイベントを定義するか、単に を使用してPropertyChanged)、コントロールを再作成できないのはなぜですか?

于 2012-04-17T06:20:41.117 に答える
1
  1. CreateBrowser() というメソッドを使用して、IBrowserCreator という名前の ViewModel にインターフェイスを作成します。
  2. ViewHelper という名前の ViewModel に静的クラスを作成し、それに BrowserCreator という名前の IBrowserCreator タイプの静的プロパティを追加します。
  3. View レイヤーで、ViewModel.IBrowserCreator を実装する BrowserCreator という新しいクラスを作成します。
  4. ビューの初期化コードで、BrowserCreator をインスタンス化し、それを ViewModel.ViewHelper.BrowserCreator に割り当てます。

ViewModel から、次を呼び出すことができるはずです。

ViewHelper.BrowserCreator.CreateBrowser()

明らかに、この回答はフレームワークにすぎませんが、一般的なアイデアが得られるはずです。正確なニーズに合わせて CreateBrowser メソッドを実装する必要があります。

于 2012-04-17T06:21:42.477 に答える
0

単純に Datatemplate を使用して、残りを WPF に任せてみませんか?

  1. Webブラウザでユーザーコントロールを作成します。ソースに直接バインドできないため、添付プロパティを追加する必要があります。

    <UserControl x:Class="WpfBrowser.BrowserControl"
             xmlns:WpfBrowser="clr-namespace:WpfBrowser" >
      <Grid>
        <WebBrowser WpfBrowser:WebBrowserUtility.BindableSource="{Binding MyPdf}"/>
      </Grid>
    </UserControl>
    
  2. あなたのURIを処理するビューモデルを作成します

    public class MyPdfVM
    {
      public Uri MyPdf { get; set; }
    
      public MyPdfVM()
      {
        this.MyPdf = new Uri(@"mypdf path"); 
      }
    }
    
  3. pageviewmodel を取得し、pdfviewmodel を追加して、ビューで contentcontrol を取得します

    public class MyPageViewmodel: INotifyPropertyChanged
    {
      private MyPdfVM _myPdfStuff;
      public MyPdfVM MyPdfStuff
      {
        get { return _myPdfStuff; }
        set { _myPdfStuff = value; this.NotifyPropertyChanged(()=>this.MyPdfStuff);}
      }
    
      public MyViewmodel()
      {
        this.MyPdfStuff = new MyPdfVM();
      }
    
      public event PropertyChangedEventHandler PropertyChanged;
      protected void NotifyPropertyChanged<T>(Expression<Func<T>> property)
      {
        var propertyInfo = ((MemberExpression)property.Body).Member as PropertyInfo;
    
        if (propertyInfo == null)
        {
            throw new ArgumentException("The lambda expression 'property' should point to a valid Property");
        }
    
        var handler = PropertyChanged;
    
        if (handler != null)
            handler(this, new PropertyChangedEventArgs(propertyInfo.Name));
      }
    }
    

window.xaml

    <Window x:Class="WpfBrowser.MainWindow"
            xmlns:WpfBrowser="clr-namespace:WpfBrowser" 
            Title="MainWindow" Height="350" Width="525">
     <Window.Resources>
       <DataTemplate DataType="{x:Type WpfBrowser:MyPdfVM}">
        <WpfBrowser:BrowserControl />
       </DataTemplate>
     </Window.Resources>
     <Grid>
       <Grid.RowDefinitions>
        <RowDefinition Height="64*" />
        <RowDefinition Height="247*" />
       </Grid.RowDefinitions>
      <Button Content="Button" Height="23" HorizontalAlignment="Left" Margin="32,14,0,0" Name="button1" VerticalAlignment="Top" Width="75" Click="button1_Click" />
      <ContentControl Grid.Row="1" Content="{Binding MyPdfStuff}"/>
     </Grid>
    </Window>

window.xaml.cs

public partial class MainWindow : Window
{
    private MyViewmodel _data;
    public MainWindow()
    {
        _data = new MyViewmodel();
        InitializeComponent();
        this.DataContext = _data;
    }

    private void button1_Click(object sender, RoutedEventArgs e)
    {
        this._data.MyPdfStuff = new MyPdfVM() { MyPdf = new Uri(@"your other pdf path for testing") };
    }
}

MyPdfStuff プロパティを変更するたびに、Web ブラウザが pdf を更新します。

附属財産

public static class WebBrowserUtility
{
    public static readonly DependencyProperty BindableSourceProperty =
        DependencyProperty.RegisterAttached("BindableSource", typeof(string), typeof(WebBrowserUtility), new UIPropertyMetadata(null, BindableSourcePropertyChanged));

    public static string GetBindableSource(DependencyObject obj)
    {
        return (string)obj.GetValue(BindableSourceProperty);
    }

    public static void SetBindableSource(DependencyObject obj, string value)
    {
        obj.SetValue(BindableSourceProperty, value);
    }

    public static void BindableSourcePropertyChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
    {
        WebBrowser browser = o as WebBrowser;
        if (browser != null)
        {
            string uri = e.NewValue as string;
            browser.Source = string.IsNullOrWhiteSpace(uri) ? null:new Uri(uri);
        }
    }

}

編集:PDFViewmodelを変更すると、ブラウザコントロールが新しいpdfを表示することがわかるように、いくつかのコードを追加しました。

于 2012-04-17T06:57:54.533 に答える