in this SO questionと同様の問題が発生しました。提案されている解決策は、表示する各現在のページ(PDF)に対して新しいWebBrowserコントロールを作成することです(古いWebBrowserコントロールを上書きする)。 MVVMのような新しいコントロールを作成する正しい方法は何ですか?私はVMのビューの実装については無知を維持しようとしています。MVVMに違反することなくビュー内にコントロールの新しいインスタンスを作成するには
答えて
なぜVMは知る必要がありますか?なぜ、ビューが適切なイベントにフックすることができないのですか(好きな場合は定義するか、PropertyChanged
を使用するだけです)、コントロールを再作成するのはなぜですか?
- ViewModelで、CreateBrowser()というメソッドを使用して、IBrowserCreatorという名前のインターフェイスを作成します。
- ViewHelperというViewModelで静的クラスを作成し、BrowserCreatorという名前のIBrowserCreator型の静的プロパティを追加します。
- Viewレイヤーで、ViewModel.IBrowserCreatorを実装するBrowserCreatorという新しいクラスを作成します。
- View初期化コードで、BrowserCreatorをインスタンス化し、ViewModel.ViewHelper.BrowserCreatorに割り当てます。あなたのViewModelから
、あなたが今呼び出すことができるはずです。
ViewHelper.BrowserCreator.CreateBrowser()
明らかにこの答えは唯一のフレームワークですが、それはあなたの一般的なアイデアを与える必要があります。正確なニーズに合わせてCreateBrowserメソッドを実装する必要があります。
ありがとう!私はこのソリューションが本当に好きですが、私はケント・ブーガートが提案しているより単純なアプローチを忘れていて、私の場合には可能です。 – OSH
私が実際にこのソリューションで気に入らないのは、静的なプロパティを持つことです。 VMとVのインスタンスが同時に複数ある場合はどうなりますか?場合によっては解決策が適切かもしれませんが、私はそれをお勧めしません。 Kent Boogaartの方法は、よりシンプルで柔軟性があります。 –
単にDatatemplateを使用してWPFに残りの処理をさせてみませんか?
webbrowserでusercontrolを作成します。直接ソースにバインドすることはできないため、接続プロパティを追加する必要があります。
<UserControl x:Class="WpfBrowser.BrowserControl" xmlns:WpfBrowser="clr-namespace:WpfBrowser" > <Grid> <WebBrowser WpfBrowser:WebBrowserUtility.BindableSource="{Binding MyPdf}"/> </Grid> </UserControl>
-
public class MyPdfVM { public Uri MyPdf { get; set; } public MyPdfVM() { this.MyPdf = new Uri(@"mypdf path"); } }
は、あなたのpageviewmodelを取るpdfviewmodelを追加し、ビューに
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をContentControlにを取るあなたのURIを扱うのviewmodelを作成します
あなたがMyPdfStuffプロパティを変更史上webbroswerは、PDFを更新<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") };
}
}
。
添付プロパティ
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);
}
}
}
EDIT:あなたはあなたがPDFViewmodel chane場合は、あなたのbrowsercontrolは新しいPDFを表示することを見ることができるようにいくつかのコードを追加しました。
- 1. ドラッグ&ドロップによる新しいビューの作成とコントロール(カスタムレイアウト)
- 2. UWP App Dynamic Pivot MVVMは常にviewmodelの新しいインスタンスを作成します
- 3. MVVM - datatemplateは新しいビューを作成します
- 4. 新しいインスタンスを作成するのではなくフラグメントを更新することはできますか?
- 5. MVVMのパターンに従って動的にコントロールを作成する
- 6. MVVMLight UserControlビューモデル - ビューごとにユーザーコントロールの新しいインスタンスを作成します。
- 7. MVVM - コントロール対ビュー
- 8. 新しいインスタンスを動的に作成するには?
- 9. リクエストごとに新しいインスタンスを作成するのではなく、DB接続を再利用する
- 10. 同時に新しいインスタンスを更新して作成する
- 11. TestNGメソッドテストごとに新しいインスタンスを作成する
- 12. Typescriptで型の新しいインスタンスを作成するには?
- 13. MVVMで動的にコントロールを作成する
- 14. iOS - MVVMで動的にコントロールを作成する
- 15. MVVMで「ルックレス」ビューを作成する
- 16. MVVMに質問するMVVMにしないでください
- 17. ループ内にJLabelとactionListenerの新しいインスタンスを作成します
- 18. ライセンスに違反することなくopensourceプロジェクトをforkする方法は?
- 19. タッチに反応するビューを作成する方法(タップではない)
- 20. ベースクラス内からサブクラスの新しいインスタンスを作成する
- 21. C#MVVM動的にビューを作成する方法
- 22. MVVM - ビューモデルをビューにバインドするには
- 23. インスタンスの作成とパラメータとしてのインスタンスと作成インスタンスとの間のパラメータの違いは何ですか?
- 24. forループ内にインスタンスを作成する
- 25. クラスの現在のインスタンスを新しく作成したインスタンスに渡します
- 26. RelayCommandの一般的な実装はMVVMパターンに違反していますか?
- 27. 新しいコントロールを作成せずに重複するフレーム
- 28. 新しいインスタンスを開くことなくフォームにデータを返す
- 29. OpenGLビューのコントロールを作成する
- 30. アクセス違反エラーポインタリストへのポインタを作成するときに
ええ、それはMVVMの本当の意味です。このアプローチの正しさを証明する別のアイデアを追加したいと思います。 OPのある時点で、OPがパネルやウィンドウ、あるいはWebブラウザの代わりに何かにコンテンツを表示する必要があると判断した場合、変更する唯一のものは小さなコードですそのコンテンツをどのように表示するかを決定するビューに表示されます。 VMは元のままです。 –