8

私は現時点でWPFとMVVMを学んでいます(または少なくとも私はしようとしています...)。

2 つのボタンを持つウィンドウを表示する小さなサンプル アプリを作成しました。それぞれのボタンをクリックすると、新しいビューが表示されます。そこで、3 つの UserControls を作成しました (DecisonMaker には 2 つのボタンがあり、「クリックターゲット」ごとに 1 つの Usercontrol)。

そこで、MainWindow の CotentControl を MainWindowViewModel の「CurrentView」というプロパティにバインドしました。

MainWindow.xaml のコード:

<Window x:Class="WpfTestApplication.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:WpfTestApplication"
    Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
    <local:MainWindowViewModel />
</Window.DataContext>
<Grid>
    <ContentControl Content="{Binding CurrentView, Mode=OneWay}" />
</Grid>
</Window>

MainWindowViewModel のコード:

class MainWindowViewModel
{      
    private UserControl _currentView = new DecisionMaker();
    public UserControl CurrentView
    {
        get { return _currentView; }
        set { _currentView = value; }
    }

    public ICommand MausCommand
    {
        get { return new RelayCommand(LoadMouseView); }
    }

    public ICommand TouchCommand
    {
        get { return new RelayCommand(LoadTouchView); }
    }

    private void LoadMouseView()
    {
        CurrentView = new UserControlMouse();
    }

    private void LoadTouchView()
    {
        CurrentView = new UserControlTouch();
    }
}

最初の UserControl (DecisionMaker) は想定どおりに表示されます。メソッドLoadMouseViewも呼び出されます。しかし、ビューは変更されません。私は何が欠けていますか?

更新:どうもありがとうございました! INotifyPropertyChanged インターフェイスを見逃していました。あなたの答えはすべて素晴らしく、非常に正確で役に立ちました!どれを受け入れたらいいのかわからない -「最初の」答えを受け入れるのが最も公正な方法だと思いますか?

問題を解決し、MVVMをよりよく理解するのに役立ったので、盲目の答えを受け入れました。でも、皆さんのおかげでどの回答も本当に素晴らしかったです!

4

5 に答える 5

7

mvvm を実行したい場合は、ビューモデルにビュー/ユーザー コントロールへの参照を含めないでください。INotifyPropertyChangedを実装する必要があります。ps: Viewmodel に System.Windows 名前空間が必要な場合は、何か問題があります。

あなたの場合、必要なもの:

  • 1メインビューモデル
  • UserControlMouse 用の 1 つのビューモデル
  • UserControlTouch 用の 1 つのビューモデル
  • UserControlMouse 用の 1 つのビュー/ユーザー コントロール
  • UserControlTouch 用の 1 つのビュー/ユーザー コントロール

mainviewmodel には、ビューを切り替えるための少なくとも 2 つのコマンドと、CurrentView の 1 つのプロパティが必要です。コマンドでは、CurrentView を適切なビューモデル インスタンスに設定するだけです。少なくとも、適切なビューを定義するビューモデルごとに 2 つのデータ テンプレートが必要です。

public object CurrentView
{
    get { return _currentView; }
    set {
        _currentView = value; this.RaiseNotifyPropertyChanged("CurrentView");}
}

xaml

<Window x:Class="WpfTestApplication.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfTestApplication"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
 <DataTemplate DataType="{x:Type local:MyMouseViewModel}">
   <local:MyMouseUserControlView/>
  </DataTemplate>
 <DataTemplate DataType="{x:Type local:MyTouchViewModel}">
   <local:MyTouchUserControlView/>
  </DataTemplate>
</Window.Resources>
<Window.DataContext>
 <local:MainWindowViewModel />
</Window.DataContext>
<Grid>

 <!-- here your buttons with command binding, i'm too lazy to write this. -->

 <!-- you content control -->
 <ContentControl Content="{Binding CurrentView, Mode=OneWay}" />
</Grid>
</Window>
于 2012-06-12T09:16:42.023 に答える
2

The viewmodel need to implement INotifyPropertyChanged. Otherwise the view won't be notified when a property changes in the viewmodel.

class MainWindowViewModel : INotifyPropertyChanged
{
    private UserControl _currentView = new DecisionMaker();

    public UserControl CurrentView
    {
        get { return _currentView; }
        set
        {
            _currentView = value;
            OnPropertyChanged("CurrentView");
        }
    } 

    public event PropertyChangedEventHandler PropertyChanged;
    private void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}
于 2012-06-12T09:08:06.877 に答える
1

あなたが望む動作は、あなたが得るものとほとんど同じように[TabControl][1]思えます - この組み込みコントロールを使用してDataContext、両方のタブを同じビューモデルにバインドしてみませんか。

これには、ビュー モデルがビュー クラスを認識しないという利点もあります ( UserControlMouseetc はユーザー コントロールであると想定しています)。

注: ビュー モデルがタッチ モードかマウス モードかを認識する必要がある場合、これは適用されません。

于 2012-06-12T09:09:57.487 に答える
1

プロパティが変更されたときにビューに通知されるように、INotifyPropertyChangedonを実装する必要があります。MainWindowViewModelCurrentView

于 2012-06-12T09:08:25.740 に答える