2017-02-20 13 views
0

viewModelで宣言されたプロパティをバインドして別のviewModelから値を取得するにはどうすればよいですか?wpf ViewModelプロパティ他のビューモデルからバインドする

InvoiceViewModel(ユーザーコントロールまたはウィンドウまたはDataTemplateのであれば私の請求書のデザインに関係なく)

私は2つのviewmodels(を実装INotifyPropertyChangedの)と1ビュー

InvoiceViewを持って

を説明しましょう

NoteListingVM

I(これのviewmodelは、それがTableRefIDプロパティレットの名前を持っています) N ViewInvoice私はそれとエキスパンダは、特定のinvoiceIDにリンクされているいくつかのノートを表示する(NoteListingVM)にDataContextのセットをだ持っ

i「はバインディング」は以下の

<Expander Header="NOTES" DockPanel.Dock="Top" Foreground="{StaticResource AlternateForeGround}"> 
        <DockPanel> 
         <DockPanel.DataContext> 
          <WendBooks:NoteListingVM TableRefID="{Binding InvoiceID}" x:Name="TransactionNotes"></WendBooks:NoteListingVM> 
         </DockPanel.DataContext> 

Aしようとすると、私は問題を抱えていますタイプ 'NoteListingVM'の 'TableRefID'プロパティで設定することはできません。 「Binding」は、DependencyObjectのDependencyPropertyにのみ設定できます。

エラーが言ったように、私はプロパティを使用することはできません。

私はDependencyPropertyを使用すると思います。しかし、InotifyPropertyChangedを実装すると、DependencyPropertyはViewModelで正常に動作しません。 (これは、ViewModelを実装するときにほとんどのユーザーが提案するものです(「INotifyPropertychanged」)

DependencyPropertysは、userControlまたはCustomControlがあるときにうまく機能します。しかし、これは私の場合ではありません。(InvokeIDが変更されたときに、NoteListingViewModelに "パラメータ"を割り当て/渡したいViewModelしか持っていません)

私はInvoiceIDを送信しますxaml)をNoteListingViewModelにフィルタリングして表示させ、私の前にある現在の請求書にリンクしているノートのみを表示しますか?適切な方法は何ですか?私は何か私はmvvmパターンを逃したか、または誤解していると確信していますか?

答えて

1

このようにしないでください。代わりに、ビューモデル中心の方法で行います。NoteListingVMを親ビューモデルのプロパティにします。

お互いに必要なことを知るために苦労するビューモデルを所有するビューのツリーとしてアプリケーションを構成する代わりに、独自の関係を持つビューモデルのツリーにします。自分自身のビューモデル以外のことを知る必要がないビューを飾りましょう。

以下のInvoiceIDプロパティは、変更時にNotes.InvoiceIDを更新します。やさしい。

public MyViewModel() 
{ 
    Notes = new NoteListingVM(); 
} 

private int _invoiceID = 0; 
public int InvoiceID 
{ 
    get { return _invoiceID; } 
    set 
    { 
     if (value != _invoiceID) 
     { 
      _invoiceID = value; 
      Notes.InvoiceID = this.InvoiceID; 
      OnPropertyChanged(); 
     } 
    } 
} 

private NoteListingVM _notes = null; 
public NoteListingVM Notes 
{ 
    get { return _notes; } 
    protected set 
    { 
     if (value != _notes) 
     { 
      _notes = value; 
      OnPropertyChanged(); 
     } 
    } 
} 

XAML。必要に応じてContentControlの周りにDockPanelをラップすることができます。

<Expander 
    Header="NOTES" 
    DockPanel.Dock="Top" 
    Foreground="{StaticResource AlternateForeGround}" 
    > 
    <ContentControl Content="{Binding Notes}" /> 
</Expander> 

代替

またInvoiceID依存関係プロパティを持つNotesViewUserControlを書き、XAMLでそれを結合することができます。同じものを使用しますNoteListingVM;あなたがやっているのと同じように、DataContextのプロパティを使って割り当てます。ユーザーコントロールのInvoiceID依存プロパティには、ビューモデルのInvoiceIDを更新する変更ハンドラがあり、これによりバインディングを使用してInvoiceIDを設定できます。これは、当初考えていたことを行うための「適切なXAML」の方法です。

また、UserControlとしてNoteListingVMを書き換えることもできますが、それはもっとうまくいくものですが、私はそれに多くの点がありません。

同じクラス内にviewmodel/INotifyPropertyChangedプロパティと依存関係プロパティを混在させないでください。

+0

aha :)あなたは正しいと思いますが、このような要件があるときにこれを実行するのは適切な方法ですか?中央のView Modelを他のViewModelsと分離しておくと、より便利で受け入れやすいパスにすべきですか? (どちらかの間に何らかの論理があるかどうか)考えているだけです(MVVMのパターンと用量は何とか思っています)。何とか... – user2160275

+0

@ user2160275誰があなたに言ったのですか?お互いにあなたのビューモデルを隠すことによって避けようとしている問題は何ですか? –

+0

はい、私はこれが間違っていると思いますか?(正解)私はNotesVVMを持っていることをInvoiceVMが知る必要があるということを意味しています。 2 ViewModelsのビューを持っています。 ViewModelsを使わずにそれらの間で値を共有してください。 – user2160275

関連する問題