2010-11-20 24 views
1

私の最初のMVVMをWPFアプリケーションで実装しようとすると。私はwinformsに基づいて古いアプリを持って、私はこのプロジェクトから私のロジック(クラス)を使用したい。WPFとMVVMの問題

私はそれがこれらのクラスで構成され、モデルを持っている:

interface IPokecService 
{ 
    bool LogOn(string nick, string password); 
    bool LogOff(); 
    JsonUser CreateJsonUser(string nick); 
    void Ping(); 
    void IbRp(); 
    bool SendRp(Rp rp); 
    Rp LoadRp(); 
} 


public class PokecService:IPokec 
{ 
public PokecAccount account; 
public PingData pingData; 

//impelent interface IPokec 

} 

私が使用してみてください。

public class FriendData 
{ 
//... 
} 

public class PingData 
{ 
//... 
} 

public class PokecAccount : INotifyPropertyChanged, IDataErrorInfo 
{ 
//... 
} 


public class Rp :INotifyPropertyChanged, IDataErrorInfo 
{ 
//... 
} 


public class JsonUser:INotifyPropertyChanged 
{ 
//... 
} 

とサービスクラスのサーバー上のHTTP GETとPOSTリクエストを送信し、このクラスは、このインタフェースを実装しますWPF Model-View-ViewModelツールキット0.1の​​DelegateCommand

ビューでは何か問題があります。しかし、私の問題はViewModelのPokecServiceクラスからメソッドを "ラップ"する方法です。

メソッドLogOnの例。

最初に私はを作成します。

StartUpWindow.xaml

<StackPanel Grid.Row="1" Margin="12,12,12,12"> 
     <Label Name="lbAzetID" Content="AzetID" Style="{StaticResource lb1}"></Label> 
     <TextBox Name="tbAzetID" Style="{StaticResource tb1}"> 
      <TextBox.Text> 
       <Binding Path="AzetId" Mode="OneWayToSource" UpdateSourceTrigger="PropertyChanged"> 
       </Binding> 
      </TextBox.Text> 
     </TextBox> 
     <Label Name="lbRegistration" Content="Registrácia" Style="{StaticResource lb1}"> 
      <Label.ToolTip> 
       <StackPanel> 
        <TextBlock FontWeight="Bold">Registrácia</TextBlock> 
        <TextBlock>Nemáte vlástené AzetID, registrujte sa tu!</TextBlock> 
       </StackPanel> 
      </Label.ToolTip> 
     </Label> 
     <Label Name="lbPassword" Content="Heslo" Style="{StaticResource lb1}" ></Label> 
     <TextBox Name="tbPassword" Style="{StaticResource tb1}"> 
      <TextBox.Text> 
       <Binding Path="Password" Mode="OneWayToSource" UpdateSourceTrigger="PropertyChanged"> 
       </Binding> 
      </TextBox.Text> 
     </TextBox> 
     <Label Name="lbForgetPassword" Content="Zabudli ste heslo?" Style="{StaticResource lb1}"> 
      <Label.ToolTip> 
       <StackPanel> 
        <TextBlock FontWeight="Bold">Zabudli ste svoje heslo?</TextBlock> 
        <TextBlock>Nechajte si ho zaslať na Váš email.</TextBlock> 
       </StackPanel> 
      </Label.ToolTip> 
     </Label> 
    </StackPanel> 
    <Button Name="LogOn" 
      Command="{Binding LogOnCommand}" 
      Content="Prihlásiť" 
      Width="100" 
      Height="25" 
      VerticalAlignment="Center" 
      Grid.Row="2" /> 

それだけで2 texboxesと1つのボタンで構成、私はビューモデルの財産上のボタンcommadをバインドします。

VieModel私はクラスDelegateCommand上PokecService、およびUIコントロールにバインドこれらのメソッドをラップします。このクラスで StartUpViewModel.cs

public class StartUpViewModel 
{ 

    private string _name = "KecMessanger"; 
    private string _password = "KecMessanger"; 
    private PokecService _pokecService; 

    public StartUpViewModel() 
    { 
     _pokecService=new PokecService(); 
    } 

    DelegateCommand _logOnCommand; 

    public ICommand LogOnCommand 
    { 
     get 
     { 
      if(_logOnCommand==null) 
      { 
       _logOnCommand=new DelegateCommand(LogOn,CanLogOn); 
      } 
      return _logOnCommand; 
     } 
    } 

    private void LogOn() 
    { 
     //In this method I need to call method LogOn from calss PokecService _pokecService.LogOn(_name,_password)   
     //if loging is success I need create another window - view and close this window 
     //somehing like this: 
     if (_pokecService.LogOn(_name, _password)) 
     { 
      var newViewWindow = new AnotherView(); 
      //close StartUpView (its typeof window) but I don’t know how 
      AnotherView.Show(); 
     }   
    } 

    private bool CanLogOn() 
    { 
     return true; 
    } 
} 

私の質問は以下のとおりです。

  1. 私はそれは問題ありません、ViewModelにのプロパティにビューからUIコントロールをバインドすることができます。 DelegateCommadを使用してViewModelのクラスPokecServiceからメソッドを「ラップする」のは良い方法ですか?

  2. 新しいウィンドウを作成する/ ViewModelで表示できますか? ViewModelで実際のView(Window)を閉じるにはどうしたらいいですか?

  3. この問題に最も適した方法は何ですか?

は私がDelegateCommand変数と私のメソッドをラップし、これらの変数プロパティの作成のみが必要だと思うと、このプロパティは、UIコントロールにバインドするが、私はMVVMでの絶対的な初心者です。私はいくつかの記事を読んでいますが、非常にシンプルなデモだけを示しています。

ありがとうございます。私の英語のために申し訳ありません。

答えて

1
  1. MVVMのビューとビューモデル間で通信するコマンドが作成されています。 PokecServiceをViewModelから抽象化するために、依存性注入(私自身はMEFを使用してください)を使用することをお勧めします。
  2. 私はビューに依存性注入を提供するので、クラスは簡単にテスト可能です。必要に応じてインタフェースを作成して、サービスクラスの実際の実装をどこにでも置き換えることなく置き換えることができます。
  3. はDIコンテナを使用します。

注:私はMVVMフレームワークとしてWAFをMEFと一緒に使用しており、魅力的に機能します。

ショート例:起動方法(すなわちApplication.OnStartup)で

[Export(typeof(IService))] 
public class Service : IService 
{ 
} 

public interface IService 
{ 
    void Method(); 
} 

[Export] 
public class Consumer 
{ 
    private readonly IService _Service; 

    [ImportingConstructor] 
    public Consumer(IService service) 
    { 
    ser = service; 
    } 


    public void DoStuff() 
    { 
    //stuff 
    _Service.Method(); 
    } 
} 

var catalog = new AssemblyCatalog(System.Reflection.Assembly.GetExecutingAssembly()); //insert the assembly defining the mentioned classes above 
var container = new CompositionContainer(catalog); 
container.ComposeParts(this); 

Consumer c = container.GetExportedValue<Consumer>(); 
c.DoStuff(); 
+0

どのように私はPokecService方法への依存性注入を使用することができますか?それは複雑に思えます。 –

+0

沖井、ありがとう、おそらく私はダムと見えるかもしれませんが、それは私の最初のWPFアプリです。あなたは、サービスクラスを公開するロードクラスConsumerでの例題リフレクションで使用します。しかし、DelegetCommandメソッドでは、コンシューマクラスのインスタンスも使用する必要があります。それは同じではありませんか? –

+0

'AssemblyCatalog'は、MEFで依存関係ツリーを生成する方法の1つです。クラスの実装とは関係がありません。また、解析を実行するアセンブリを取得するためにリフレクションが使用されます。私が言ったように、コマンドはviewmodelとサービスではなく、viewとviewmodelの間の通信のためのものです。 – Femaref