2012-02-16 18 views
1

私はマルチスレッドWPFアプリケーションでMVVMパターンを使用します。スレッドで作成されたオブジェクトのプロパティへのバインド

public class ShallowModel : INotifyPropertyChanged 
{ 
    private string _dbState; 
    public string DbState 
    { 
    get { return _dbState; } 
    set 
    { 
     _dbState = value; 
     OnPropertyChanged("DbState") // ofc there is implementation of this 
    } 
    } 
    private InsideObject _inObject; 
    public InsideObject InObject 
    { 
    get { return _inObject; } 
    set 
    { 
     _inObject = value; 
     OnPropertyChanged("InObject") 
    } 
    } 
} 

public class InsideModel : INotifyPropertyChanged 
{ 
    private string _actState; 
    public string ActState 
    { 
    get { return _actState; } 
    set 
    { 
     _actState= value; 
     OnPropertyChanged("ActState") 
    } 
    } 
} 

は私が見るにテキストブロックを持っていると言う:

<TextBlock Text={Binding ActObjectState}/> 
<TextBlock Text={Binding DbState}/> 

今があります、私は(私はそれがより明確にするためにINotifyPropertyChangedインターフェイスの明白な実装をスキップ)を持つモデルで今

問題のあるViewModelの一部:

public class ViewModel : INotifyPropertyChanged 
{ 
    private ShallowModel _model; 
    public string ActObjectState 
    { 
    get 
    { 
     if(_model.InObject != null) 
     return _model.InObject.ActState; 
     else 
     return null; 
    } 
    } 
    public string DbState 
    { 
    get 
    { 
     return _model.DbState; 
    } 
    } 
} 

問題は、ActObjectStaバックグラウンドスレッドがShallowModelおよび/またはInsideModelのプロパティを更新しているときに、teおよびDbStateが更新されていません。私の質問は以下のとおりです。

  1. は私が{= Model.DbStateバインディングのパス}のようにViewModelにバインドビューにモデルのパブリックプロパティを追加すべきか?私はそれがMVVMのアイデアを混乱させると思う - ビューはモデルについて知っているべきではない。

  2. InObject in ShallowModelは、UI上のユーザークリックボタンの後に新しいスレッドによって作成されます。したがって、ViewModelが作成されるとき、InObjectはnullです。何とか - スレッドによって作成された後 - ActObjectStateは更新されません。それを動作させるには? {Binding Path = Model.InObject.ActState}のようなバインディングを作成しますか?これは、UIデザイナーによるモデルに関する知識を必要とすることを意味します。

Thxを、私の英語

+0

これは間違いなくあなたを助ける必要があることを知っていると思う[継承INotifyPropertyChangedの] [1] [1]:http://stackoverflow.com/質問/ 6871952/silverlight-checkbox-results –

+0

あなたは何を正確に参照しているのか分かりません。全体のINotifyPropertyChangedインタフェースが実装されています。これらのプロパティがViewModelではなくModelで設定されていても、ViewModelでも使用する必要があります。両方ともバックグラウンドスレッドのアクションの結果として設定されます。 – Joe

+0

間違ったコードがすべて表示されています。あなたの問題は、バインドされたプロパティでUIを更新することですが、INotifyPropertyChangedの実装は表示されません。バックグラウンドスレッドがこれらのプロパティを更新しているのに、コードを表示していないとします。 –

答えて

0

私はあなたの提案を受け取ります。その最も簡単な方法ですが、私はMVVMパターンに違反することはありません。

これはあなたのために動作しない場合 - viewmodelにビューに関連するロジックを配置する必要があります。 viewmodelがモデルの変更を監視し、(ビューに関連するロジックを使用して)これらの変更をビューに再スローする必要があるかもしれません。

ディスパッチャものを意識するスレッドでの作業が、私はあなたが

+0

私はディスパッチャーを使用し、必要に応じて呼び出します。どうも。私はモデルによって更新されるUIが必要です。だから私はいくつかのモデルロジックをviewmodelに入れて、それがうまくいくと思う。私の1.提案は私のために一種の汚れているようです。 – Joe

+0

最後に、アイデアの欠如(またはAnton Tykhyyが書いていたようなsthを実装する時間)のために、私は#1を提案しました。皆さんありがとうございました。 – Joe

0

ためSRYあなたのスレッドは、あなたがのviewmodelにそれに関連するすべてのプロパティを調達する必要がShallowModelを作成した場合。 String.Emptyを生成して、データバインドエンジンにバインドされたすべてのプロパティを取得させることができます。しかし、スレッド内にいるので、PropertyChangedEventを送信するだけでUIスレッドが処理できるようにする必要はありません。私たちがしたのは、dispatcherでRaise Methodをスレッドセーフにすることでした。

+0

実際にShallowObjectがViewModelに渡されます。 InsideObjectはスレッドによって作成されます。例外はありません。それはちょうど更新ではない。いくつかの答えを待っている間、私はすべてのプロセスがUIスレッドによって行われる単純なアプリケーションを構築しました。それは機能していませんでした。 || ViewModelのプロパティを 'String.Empty'に設定することを意味しますか? – Joe

+0

@Joeちょっとしたこと...これはTypoですか? AstState != ActState。 – dowhilefor

+0

さて、申し訳ありません。修正されました。 – Joe

関連する問題