如何获取原始ViewModel?

时间:2016-06-20 04:03:32

标签: wpf mvvm

我创建了一个用户控件,其ViewModelA()作为ViewModel,然后在我的View中,有一个StackPanel,它使用ViewModelA.Data作为DataContext。

我的问题在于这个StackPanel,我有一个按钮,需要在ViewModelA()中实现我创建的ICommand。我怎么能这样做?

<Button DataContext="DataContext.Parent" />之类的东西吗?

以下是我实现ViewModel和View的方法:

的App.xaml

<DataTemplate DataType="{x:Type vm:ViewModelA}">
    <vw:ViewA />
</DataTemplate>

ViewA.xaml(堆栈面板内的按钮应该实现ICommand)

<StackPanel x:Name="RightPaneDetails"
            Grid.Column="1"
            Margin="15,0,0,30"
            DataContext="{Binding Data}">
    <!-- Some controls goes here that binds to ViewModelA.Data properties -->
    <StackPanel Orientation="Horizontal">
        <Button DataContext={Binding} Command="{Binding LookupCommand}" /> <!-- This button should implement the ViewModelA.LookupCommand -->
    </StackPanel>
</StackPanel>

TIA

PS,ViewModelA.Data是我的模特。

2 个答案:

答案 0 :(得分:1)

您的UC中似乎已将DataContext设置为ViewModelA。所以,你可以使用

<Button DataContext={Binding} Command="{Binding DataContext.LookupCommand, RelativeSource={RelativeSource AncestorType=UserControl, Mode=FindAncestor}}" />

它也可以写成:

<Button DataContext={Binding DataContext, RelativeSource={RelativeSource AncestorType=UserControl, Mode=FindAncestor} } Command="{Binding LookupCommand}" />

答案 1 :(得分:0)

虽然@ AnjumSKhan的解决方案是正确的,但我想提出替代解决方案:

<StackPanel x:Name="RightPaneDetails"> <!-- do not set bind datacontext here -->

    <!-- Some controls goes here that binds to ViewModelA.Data properties, e.g: -->
    <TextBlock Text="{Binding Data.SomeProperty}" />
    <!-- If there too many elements bound to Data, you can group them in stackpanel -->


    <StackPanel Orientation="Horizontal">
        <!-- This button is databound to ViewModelA.LookupCommand 
             DataContext doesn't have to be set, since it's inherited from parent. Actually entire stackpanel is redundant here-->
        <Button Command="{Binding LookupCommand}" /> 
    </StackPanel>
</StackPanel>

正如您所看到的,我只是避免在父RightPaneDetails上设置DataContext,这样孩子们就可以轻松访问ViewModelA.Data的属性(TextBlock)和ViewModelA的属性(Button)

<小时/> 其他几点说明:

  1. 请注意,而不是

    RelativeSource={RelativeSource AncestorType=UserControl, Mode=FindAncestor} 
    

    你可以写

    RelativeSource={RelativeSource AncestorType=UserControl}
    
  2. RelativeSource的替代解决方案是ElementName:

    <StackPanel x:Name="Root">
      <StackPanel DataContext="{Binding Data}">
        <Button Command="{Binding DataContext.LookupCommand, ElementName=Root}" />
    

    我喜欢这个因为&#34; Root&#34;在编译时检查元素,它更具可读性。

  3. 避免在同一元素上绑定DataContext和另一个Property,例如:

    <Button DataContext="{Binding....}" Command="{Binding ...}" />
    

    无法保证首先评估哪种绑定。但是,您可以将IsAsyc = True设置为第二个绑定Command={Binding ..., IsAsync=True},以确保它的评估时间晚于非异步绑定