6

ビューにバインドされているメインウィンドウを作成しようとしています。コードでそのビューを変更し、メインウィンドウで更新されることを期待していますが、それは発生していません。

XAMLにこのコードがあります

<Grid>
    <ContentControl Content="{Binding Source={StaticResource ViewModelLocator}, Path=MainWindowViewModel.CurrentControl}" />
</Grid>

次に、このコードを使用してコントロールを変更します

public class MainWindowViewModel : ReactiveObject
{
    private UserControl _CurrentControl = null;
    public UserControl CurrentControl
    {
        get
        {
            if (_CurrentControl == null)
            {
                _CurrentControl = new HomePage();
            }
            return _CurrentControl;
        }
        set
        {
            this.RaiseAndSetIfChanged(x => x.CurrentControl, value);
        }
    }
}

ご覧のとおり、私はReactiveUIライブラリを使用しています。

そのビューで使用するのはContentControl間違っているのですか、それともバインドと更新が正しく行われていないだけですか?

4

3 に答える 3

10

を使用して、実際にはこれを行うためのはるかに優れた方法がありますViewModelViewHost

<Grid DataContext="{Binding ViewModel, ElementName=TheUserControl}">
    <ViewModelViewHost ViewModel="{Binding CurrentControlViewModel}" />
</Grid>

これで、クラスは次のようになります。

public class MainWindowViewModel : ReactiveObject
{
    private ReactiveObject _CurrentControlViewModel = new HomePageViewModel();
    public ReactiveObject CurrentControlViewModel {
        get { return _CurrentControl; }
        set { this.RaiseAndSetIfChanged(x => x.CurrentControlViewModel, value); }
    }
}

アプリのスタートアップのどこかに、次のように書く必要があります。

RxApp.Register(typeof(IViewFor<HomePageViewModel>), typeof(HomePage));

ViewModelViewHost とは

ViewModelViewHostBindings を介して提供する ViewModel オブジェクトを取得し、Service Location を使用して、それに適合する View を検索します。Register 呼び出しは、View を ViewModel に関連付ける方法です。

于 2013-03-12T21:07:30.293 に答える
5

クラスを MainWindowViewModel と呼ぶのはなぜですか? mvvm を実行したい場合は、VM に UserControl タイプのプロパティを設定しないでください。

通常の mvvm の方法は次のようになります。

  • INotifyPropertyChanged を使用したビューモデル
public class MyViewmodel
{
    public IWorkspace MyContent {get;set;}
}
  • VM にバインドする xaml コンテンツ コントロール
<ContentControl Content="{Binding MyContent}"/>
  • datatemplate --> wpf が IWorkspace のレンダリング方法を認識できるように
<DataTemplate DataType="{x:Type local:MyIWorkSpaceImplementationType}" >
   <view:MyWorkspaceView />
</DataTemplate>
于 2013-03-12T07:30:54.210 に答える
3

ここにはいくつかの混乱した概念があり、それらが互いに干渉していると思います。

まず、reactiveUI コードを実際に使用していないため、呼び出されることはありません。get アクセサーは遅延インスタンス化パターンを実装しているため、set アクセサーは無視されます。これは、ビューがプロパティの変更を通知しないため、更新を取得できないことを意味します。

もっと似たものを使うことをお勧めします

private UserControl _currentControl;

public MainWindowVirwModel()
{
  CurrentControl = new HomePage();
}

public UserControl CurrentControl
{
  get { return _curentControl;}
  set { this.RaiseAndSetIfChanged(...); }
}

さらに、これは ViewModel 層内の View コンポーネント、つまり HomePage を依然として混同し、単体テストをはるかに困難にします。

于 2013-03-12T08:25:26.280 に答える