【问题标题】:How ist the DataContext of a Unsercontrol related to its DependencyProperties?Usercontrol 的 DataContext 与它的 Dependency Properties 有什么关系?
【发布时间】:2015-03-21 00:38:05
【问题描述】:

在使用具有 DependencyProperties 的 UserControl 时,我意识到考虑在哪里设置 DataContext 是很重要的。为了描绘它,我创建了一个示例应用程序。有两个 UserControl,除了设置 DataContext 的位置之外,它们都是相等的:

工作用户控件:

<UserControl x:Class="DpropTest.OkUserControl"
         ...>
    <Grid DataContext="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=dpropTest:OkUserControl }}">
        <TextBlock Text="{Binding Path=MyDepProp}"></TextBlock>
    </Grid>
</UserControl>

用户控件不起作用:

<UserControl x:Class="DpropTest.NotOkUserControl"
         ...
         DataContext="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=dpropTest:NotOkUserControl}}" 
         >
<Grid >
    <TextBlock Text="{Binding Path=MyDepProp}"></TextBlock>
</Grid>

两个 UserControl 都有一个名为 MyDepProp 的 DependencyProperty,

 #region Dependency Property Declaration
    public static readonly DependencyProperty MyDepPropProperty = DependencyProperty.Register(
        "MyDepProp", typeof(string), typeof(NotOkUserControl), new PropertyMetadata(default(string)));

    public string MyDepProp
    {
        get { return (string)GetValue(MyDepPropProperty); }
        set { SetValue(MyDepPropProperty, value); }
    }
    #endregion Dependency Property Declaration

这就是我将用户控件集成到主窗口的方式:

<Grid x:Name="ParentGrid">
    <StackPanel>
        <dpropTest:OkUserControl MyDepProp="{Binding Path=ActualWidth, ElementName=ParentGrid}"/>
        <dpropTest:NotOkUserControl MyDepProp="{Binding Path=ActualWidth, ElementName=ParentGrid}"/>
    </StackPanel>
</Grid>

正在运行的应用程序仅显示第一个 UserControl 的 actualWith,第二个 UserControl 保持未设置,因为 DP 未绑定。

关于第二个 UserControl 的输出窗口中没有错误...

也许有一个 WPF Pro 有一个简短的解释? 谢谢! 乌力

【问题讨论】:

    标签: wpf dependency-properties datacontext


    【解决方案1】:
    <UserControl x:Class="DpropTest.NotOkUserControl"
             ...
             DataContext="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=dpropTest:OkUserControl }}"
    

    在我看来,您绑定到了错误的父级!您在 NotOkUserControl 内部,但您要求的是无法访问的 AncestorType...

    【讨论】:

    • NotOkUserControl 仍然不是它自己的祖先。
    • 其实这就是我困惑的根源。与 UserControls 之间的唯一区别是,对于工作的 DataContext 设置在 LayoutRoot: 其中对于在类
    • 再读一遍我写给你的。您绑定到错误的父级,这就是您没有 DataContext 的原因。在 NotOkUserControl 的标头中寻找 AncestorType = OKUserControl 没有任何意义。考虑更改绑定定义。在 VisualTree 中定义相对绑定的位置也很重要
    • 嗨,对不起,我打错了,我将绑定更改为正确的类型 NotOkUserControl,行为没有改变。是否可以加载源文件?谢谢!
    • 我想你误解了我的意思 :) 我是说无论你选择什么 AncestorType,你的绑定通常都是完全错误的。 {Binding RelativeSource={RelativeSource Self}} 可能会解决您的问题。至少你会有 DataContext 然后
    【解决方案2】:

    我认为 FindAncestor 不会从元素本身开始,但除此之外:您可以在 UserControl 上设置它:

    DataContext="{Binding RelativeSource={RelativeSource Self}}"
    

    或在用户控件的构造函数中,在 InitializeComponent 之前设置:

    DataContext = this;
    

    附带说明:通常不需要绑定某些祖先的 ActualWidth;在这种情况下,堆栈面板的宽度与其父网格的宽度相同,用户控件的宽度与堆栈面板的宽度相同。所以实际上 MyDepProp 等于用户控件的 ActualWidth。

    【讨论】:

    • 实际上它与 ActualWith 无关,我只是拖动该属性以获取快速示例。我不明白为什么无论 dataContext 是在 上还是在包含的 FrameworkElement 上声明的,它显然有很大的不同。
    猜你喜欢
    • 1970-01-01
    • 2011-03-28
    • 2019-07-22
    • 2012-03-12
    • 2012-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-03
    相关资源
    最近更新 更多