如何从UserControl访问父级的DataContext

时间:2011-07-04 19:00:49

标签: wpf user-controls datacontext

我需要从UserControl(包含文本框和列表框的网格:我需要在此列表框中插入项目)访问容器的DataContext,这是我在WPF中创建的:这是最好的方法吗?

我正在考虑将DataContext作为参数传递给用户控件,但认为有一种更简洁的方法。

4 个答案:

答案 0 :(得分:11)

通常DataContext将是inherited,只是不要在UserControl上明确设置它,它将从其父级获取它。如果你必须设置它,你仍然可以使用Parent属性来获取父级,然后你可以安全地转换为FrameworkElement,如果它不是null,你可以抓住它{{1} }。

答案 1 :(得分:7)

我有时会嵌套用户控件,而孙用户控件有时需要祖父母视图的数据上下文。到目前为止我找到的最简单的方法(我有点新手)是使用以下内容:

<Shared:GranchildControl DataContext="{Binding RelativeSource={RelativeSource 
                    FindAncestor, AncestorType={x:Type GrandparentView}},
                    Path=DataContext.GrandparentViewModel}" />

如果你想要更多细节,我在我的博客上写了more detailed example

答案 2 :(得分:2)

将此BindingProxy类添加到项目中:

Data="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}},Path=DataContext}"
  1. 将BindingProxy添加到UserControl的资源中。
  2. 设置&#39;数据&#39; BindingProxy的属性,无论你需要什么,例如搜索父窗口。 {Binding Data.MyCommand, Source={StaticResource BindingProxy}}如果您需要更复杂的东西,可以使用自定义转换器。
  3. 现在您可以访问该父级的DataContext:<UserControl xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:common="clr-namespace:YourNameSpace;assembly=YourAssembly" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="300"> <UserControl.Resources> <common:BindingProxy x:Key="BindingProxy" Data="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}},Path=DataContext}" /> </UserControl.Resources> <Border> <Button Command="{Binding Data.MyCommand, Source={StaticResource BindingProxy}}">Execute My Command</Button> <!-- some visual stuff --> </Border> </UserControl>

    n

答案 3 :(得分:1)

H.B。回答你标题中的问题。

然而,该文本提出了一个不同的设计问题。我请你重新考虑你的设计。

只要两者之间没有显式覆盖,控件就会继承其祖先的DataContext属性。
如果用户控件需要数据,则应从其数据源(用户控件的视图模型)获取数据。因此,在这种情况下,用户控件可以从ListItemsForDisplay实例上公开的SomeViewModel属性获取所需的数据。没有必要得到父母和演员..更清洁。

<ContainerType DataSource={Binding SomeViewModel}>
  <YourUserControl>
    <ListBox ItemsSource={Binding ListItemsForDisplay}"/>
...