我创建了一个用户控件,其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是我的模特。
答案 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)
<小时/> 其他几点说明:
请注意,而不是
RelativeSource={RelativeSource AncestorType=UserControl, Mode=FindAncestor}
你可以写
RelativeSource={RelativeSource AncestorType=UserControl}
RelativeSource的替代解决方案是ElementName:
<StackPanel x:Name="Root">
<StackPanel DataContext="{Binding Data}">
<Button Command="{Binding DataContext.LookupCommand, ElementName=Root}" />
我喜欢这个因为&#34; Root&#34;在编译时检查元素,它更具可读性。
避免在同一元素上绑定DataContext和另一个Property,例如:
<Button DataContext="{Binding....}" Command="{Binding ...}" />
无法保证首先评估哪种绑定。但是,您可以将IsAsyc = True设置为第二个绑定Command={Binding ..., IsAsync=True}
,以确保它的评估时间晚于非异步绑定