wpf来自另一个视图模型

时间:2017-02-20 21:12:35

标签: wpf properties binding viewmodel

如何绑定viewmodel中声明的属性以从另一个viewModel获取值?

让我解释一下

我有2个ViewModel(实现INotifyPropertyChanged)和1个视图

InvoiceView(只是我的发票设计,无论是用户控件还是窗口或dataTemplate)

InvoiceViewModel

NoteListingVM(此viewmodel有一个属性,将其命名为TableRefID)

在ViewInvoice中我有一个扩展器,它的dataContext设置为(NoteListingVM),以显示与特定invoiceID链接的一些注释

我尝试以下时遇到问题

 <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&#39;绑定&#39;不能在&#39; TableRefID&#39;上设置属性类型&#39; NoteListingVM&#39;。 A&#39;绑定&#39;只能在DependencyObject的DependencyProperty上设置。

因为错误说,我不能使用属性。

然后我想使用DependencyProperty。但是,如果实现InotifyPropertyChanged,则DependencyProperty无法在ViewModel中正常工作。 (这是大多数用户在实施ViewModel时建议的 - &#34; INotifyPropertychanged&#34;)

当您拥有userControl或CustomControl时,DependencyPropertys可以正常工作。但这不是我的情况(我没有usercontrol或customControl我只有一个ViewModel,我希望在InvoiceID更改时分配/传递&#34;参数&#34;到NoteListingViewModel)

那么我将如何将InvoiceID(仅限xaml)发送到NoteListingViewModel以过滤并仅显示链接到我前面的当前发票的注释?什么是正确的方法?我确定我错过了什么或误解了mvvm模式?

1 个答案:

答案 0 :(得分:2)

不要这样做。以视图模型为中心的方式来做:使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。如果需要,您可以在DockPanel周围包裹ContentControl

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

替代

您还可以编写具有NotesView依赖项属性的UserControl InvoiceID,并将其绑定在XAML中。它将使用相同的NoteListingVM;您可以通过DataContext属性分配,就像您一直在做的那样。用户控件的InvoiceID依赖项属性将具有更新处理程序,用于更新视图模型的InvoiceID,这将允许您使用绑定来设置InvoiceID。这是一个适当的XAML&#34;如何做你原来想到的。

您也可以将NoteListingVM完全重写为UserControl,但这样做的工作量更多,而且我没有看到很多指向它的内容。

您不能将viewmodel / INotifyPropertyChanged属性与同一类中的依赖项属性混合使用。