2

ViewModel でインスタンス化した UserControl に ContentControl の Content をバインドしようとしています。インスタンス化せずに、UserControls/Views の同じインスタンスを使用して ContentControl のコンテンツを頻繁に変更できるようにする必要があるため、ViewModel へのバインディングでメソッドを使用してから、UserControl を ViewModel の DataTemplate にすることはできません。再バインドするたびにビュー。

ただし、UserControl プロパティを UserControl インスタンスに設定し、ビューがレンダリング/データ バインドされると、次のようになります。新しい親 Visual にアタッチする前に、指定された子を現在の親 Visual から切断する必要があります。以前にこの UserControl をどこにも追加したことがありませんが、以前にこのインスタンスを作成してメモリに保持しました。

私がやっていることを達成するためのより良い方法はありますか?

ビューモデルで

public class MyViewModel : INotifyPropertyChanged
{
    //...

    private void LoadApps()
    {
        var instances = new List<UserControl>
                          {
                              new Instance1View(),
                              new Instance2View(),
                              new Instance3View(),
                          };
        SwitchInstances(instances);
    }

    private void SwitchInstances(List<UserControl> instances)
    {
        CenterApp = instances[0];
    }

    //...

    private UserControl _centerApp;
    public UserControl CenterApp
    {
        get { return _centerApp; }

        set
        {
            if (_centerApp == value)
            {
                return;
            }

            _centerApp = value;
            OnPropertyChanged("CenterApp");
        }
    }

    //...
}

View.xaml で

<ContentControl Content="{Binding CenterApp}"></ContentControl>
4

1 に答える 1

3

コメントが長すぎます。

あなたのコメントで@Kentが述べたことに基づいて、MVVMの全体的なポイントは、GUIアプリケーションのテスト機能をブロックするビュー関連のもの(コントロール)からビューモデルを切り離すことです。したがって、UserControl / Button / グラフィックビュー関連のアイテムを使用すると、MVVM の原則全体が無効になります。

MVVM を使用している場合は、その標準に準拠してから、問題に再度対処する必要があります。

  1. MVVM では、通常 1 つのビュー <-> 1 つのビューモデルがあります
  2. ビューはそのビュー モデルを認識します (通常は DataContext を介して)。リバースはコーディングしないでください。
  3. ビューを制御するロジックをビュー モデルに配置して、ロジックをテストできるようにします (コマンドと INPC プロパティ)。

...そして、かなりの数。ビューモデルの範囲でビュー関連のものを持たないことはかなり具体的Visibilityです。通常は aboolを保持し、ビューでコンバーターを使用してそれをVisibilityオブジェクトに切り替えます。

MVVMをもう少し読んでみると確かに役に立ちます。

今あなたの現在の問題に対処する何かのために:

MVVM構造に従って、

次のようなViewModelを使用する予定です

  • 主要: MyViewModel
  • すべてのインスタンス ViewModel をベースから派生させて、それらをリストに保持できるようにします。
  • Instance1ViewModelInstance2ViewModelInstance3ViewModelで個別にリストまたは保持MyViewModelします (自分で作成するか、IOC コンテナーを使用して注入できる場合)
  • MyViewModel投稿された例と同じようにプロパティを公開してください:

例:

// ViewModelBase is the base class for all instance View Models
private ViewModelBase _currentFrame;
public ViewModelBase CurrentFrame {
  get {
    return _currentFrame;
  }

  private set {
    if (value == _currentFrame)
      return;
    _currentFrame = value;
    OnPropertyChanged(() => CurrentFrame);
  }
}
  • ビューファイルでMyView.xaml、トップレベルの DataContext をMyViewModel
  • ビューの xaml は次のように宣言できます。

例:

...
<Window.Resources>
  <DataTemplate DataType="{x:Type local:Instance1ViewModel}">
    <local:Instance1View />
  </DataTemplate>
  <DataTemplate DataType="{x:Type local:Instance2ViewModel}">
    <local:Instance2View />
  </DataTemplate>
  <DataTemplate DataType="{x:Type local:Instance3ViewModel}">
    <local:Instance3View />
  </DataTemplate>
</Window.Resources>
<Grid>
  <ContentControl Content="{Binding Path=CurrentFrame}" />
</Grid>
...
  • それでおしまい!。ビューモデルのプロパティを切り替えてCurrentFrame、3 つのインスタンス ビューモデルのいずれかを指すようにすると、それに応じてビューが更新されます。

これにより、MVVM 準拠のアプリケーションが得られます。DataTemplate に基づいてビューを動的に再作成する必要がないという他の問題については、ここで提案されているアプローチに従い、独自の用途に合わせて拡張できます。

于 2013-03-28T21:31:20.363 に答える