Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Wpf 如何访问父';从UserControl中删除DataContext_Wpf_User Controls_Datacontext - Fatal编程技术网

Wpf 如何访问父';从UserControl中删除DataContext

Wpf 如何访问父';从UserControl中删除DataContext,wpf,user-controls,datacontext,Wpf,User Controls,Datacontext,我需要从我在WPF中创建的UserControl(一个包含文本框和列表框的网格:我需要在此列表框中插入项)访问容器的DataContext:哪种方法最好 我想把DataContext作为参数传递给用户控件,但我认为有一种更干净的方法可以做到这一点。通常情况下,DataContext会是,只是不要在UserControl上显式设置它,它会从其父控件获取它。如果必须设置它,您仍然可以使用该属性获取父元素,然后可以将其安全转换为框架元素,如果它不为null,则可以获取其数据上下文H.B。回答标题中的问

我需要从我在WPF中创建的UserControl(一个包含文本框和列表框的网格:我需要在此列表框中插入项)访问容器的DataContext:哪种方法最好


我想把DataContext作为参数传递给用户控件,但我认为有一种更干净的方法可以做到这一点。

通常情况下,
DataContext
会是,只是不要在
UserControl
上显式设置它,它会从其父控件获取它。如果必须设置它,您仍然可以使用该属性获取父元素,然后可以将其安全转换为
框架元素
,如果它不为null,则可以获取其
数据上下文
H.B。回答标题中的问题

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

控件继承其祖先的DataContext属性,只要中间没有人显式重写。
如果用户控件需要数据,则应从其数据源(用户控件的viewmodel)获取数据。因此,在这种情况下,用户控件可以从
SomeViewModel
实例上公开的
ListItemsForDisplay
属性中获取所需的数据。无需获得家长和演员。。干净多了

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


我有时有嵌套的用户控件,孙子用户控件有时需要祖父母视图的数据上下文。到目前为止,我发现的最简单的方法(我是一个新手)是使用以下方法:

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


如果您想了解更多细节,我在我的博客上写了一篇文章。

将此BindingProxy类添加到您的项目中:

using System.Windows;

namespace YourNameSpace
{
    /// <summary>
    /// Add Proxy <ut:BindingProxy x:Key="Proxy" Data="{Binding}" /> to Resources
    /// Bind like <Element Property="{Binding Data.MyValue, Source={StaticResource Proxy}}" />   
    /// </summary>
    public class BindingProxy : Freezable
    {
        protected override Freezable CreateInstanceCore()
        {
            return new BindingProxy();
        }

        public object Data
        {
            get { return (object)GetValue(DataProperty); }
            set { SetValue(DataProperty, value); }
        }

        public static readonly DependencyProperty DataProperty = DependencyProperty.Register("Data", typeof(object), typeof(BindingProxy));
    }
}

如果目标控件嵌套在一个或多个其他控件中,则目标控件的父控件可能会更改DataContext,因此您可能无法在目标控件中看到所需的对象。在我看来,应该有一堆数据上下文可供访问。@Todd:好吧,你可以编写一个方法,只需沿着树走一走,就可以得到所有唯一的
DataContexts
,我想我以前可能也做过类似的事情。这里是最好的优雅解决方案!很好的解决方案。
<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>