来自包含Control的WPF访问信息

时间:2009-05-14 19:49:48

标签: wpf user-controls

我有一个带有stackpanel的UserControl(a),它的ItemSource设置为一个集合。 然后StackPanel包含一组UserControl(b),其中包含几个按钮和一个数据网格控件。 有没有办法从UserControl(b)中的代码访问父UserControl(a)后面的代码中的属性。

基本上,当UserControl(a)加载到窗口中时,传入的参数包含是否将表单视为只读。我想将Usercontrol(b)中按钮的可见性绑定到父UserControl(a)的代码隐藏中的readonly属性。

1 个答案:

答案 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中这样做,我不确定它是否可以在那里工作(没有试图看看标记扩展是否容忍空白)。