我有一个带有stackpanel的UserControl(a),它的ItemSource设置为一个集合。 然后StackPanel包含一组UserControl(b),其中包含几个按钮和一个数据网格控件。 有没有办法从UserControl(b)中的代码访问父UserControl(a)后面的代码中的属性。
基本上,当UserControl(a)加载到窗口中时,传入的参数包含是否将表单视为只读。我想将Usercontrol(b)中按钮的可见性绑定到父UserControl(a)的代码隐藏中的readonly属性。
答案 0 :(得分:2)
通常使用WPF我建议你实现Model-View-ViewModel模式(参见MSDN)。
使用此模式,您将创建一个ViewModel,其中包含您要绑定的所有数据。这将被设置为(a)usercontrol的数据上下文。然后,该控件将其所有控件绑定到datacontext上的属性。
子(b)usercontrol将继承此datacontext,因此可以将其控件绑定到与(a)使用的属性相同的属性。这是因为datacontexts在逻辑(和可视)树中继承,直到它被覆盖为止。
因此,对于您,我将考虑创建一个包含ReadOnly属性的ViewModel。然后,您可以将此ViewModel对象设置为(a)usercontrol的datacontext。 (b)usercontrol,因为它在(a)usercontrol层次结构下将继承相同的datacontext。这将允许您将(b)中的控件绑定到与(a)相同的属性,如下所示。
<Button IsEnabled="{Binding ReadOnly}"
Context="Click me!"
Command="{Binding ClickMeCommand}" />
要在视图代码隐藏中设置datacontext,我会执行如下所示的构造函数。
public MyView(IMyViewModel viewModel)
{
InitializeComponent();
DataContext = viewModel;
}
MyView是从您的实例中的UserControl继承的类。您不必以我的方式获取视图模型,我使用Unity将视图模型注入到自动构造的视图中,因为我使用Prism但您可以将其创建为普通对象并分配它到datacontext。
请注意,我还使用datacontext将命令绑定到按钮,因为我通常也会通过ViewModel公开它们,如果您创建一个实现ICommand和委托代理的包装类,这很容易。如果您有兴趣,请参阅DelegateCommand blog article或查看Prism中的DelegateCommand类。
如果由于某种原因你覆盖了datacontext,这可能在使用master / details视图时发生,你可以将视图的详细信息部分的datacontext更改为列表中当前选定的项目,那么你仍然可以访问通过使用相对源绑定来获取父datacontext。
E.g。
<ComboBox Grid.Row="1" Grid.Column="1" x:Name="Unit" IsReadOnly="True"
ItemsSource="{Binding Path=DataContext.AvailableUnits, RelativeSource=
{RelativeSource Mode=FindAncestor,
AncestorType={x:Type Window}}}"
DisplayMemberPath="Name" SelectedItem="{Binding Unit}" />
注意ItemsSource绑定使用相对源来查找父窗口,然后绑定到它的datacontext的属性。为了清楚起见,我还在多行中的引号中拆分了ItemsSource绑定,但是不要在你的xaml中这样做,我不确定它是否可以在那里工作(没有试图看看标记扩展是否容忍空白)。