DependencyObject无法为目标元素找到管理FrameworkElement,即使该对象位于FrameworkElement的逻辑树中也是如此

Abe*_*Toy 8 .net c# wpf

在研究了一下Cannot find governing FrameworkElement or FrameworkContentElement for target element错误之后,我发现依赖对象实际上不具有可绑定的依赖属性,除非它们是FrameworkElements或者在一个元素树中.

但是,我有一个拥有DependencyObjects的FrameworkElement,我不能发送绑定到那些DependencyObjects属性,即使它们是FrameworkElement逻辑树的一部分.

我正在用子元素编写一个复杂的自定义控件,我需要这些子元素是DependencyObjects(但不是FrameworkElements,因为它们受到许多不被使用的属性的污染,并且它可能会混淆用户),而我还需要它们的DependencyProperties可绑定.

我错过了什么?还有什么我需要告诉DependencyObjects所以他们知道它们在逻辑树中吗?我应该让它们成为Freezables,即使它们被冻结也没有意义吗?

干杯

Kyl*_*Ren 2

我认为你的结论和推论并不完全正确。

首先WPF一切事物都是源自于DependencyObjectFrameworkElement阶级没有什么不同。如果你看一下类的层次结构, FrameworkElement它就像下面的顺序:

DependencyObject--> Visual--> UIElement-->FrameworkElement

Dependency Property因此,如果您尝试在从上述任何类派生的类中创建 a ,它将工作得很好(不包括直接绑定,但其他方式绑定有效(请参见下面的示例))。CustomControl您的(不确定您使用的CustomControl是 或)代码一定有问题UserControl

但是派生的类UIElement也可以DependencyProperties绑定到其他元素。

UIElement类,它有很多DependencyProperties

用户界面元素

请分享您的控件的代码,我们可以研究一下。

更新:

DependecyObject's DependencyProperty下面是如何绑定a 的示例:

DependencyObject执行:

public class MyClass : DependencyObject
{
    public MyClass()
    {
        this.Button = new Button();
        Button.Width = 500;
        Button.Height = 400;
        Button.Content = "Bound to Window Height";
    }

    private Binding height;
    public Binding Height
    {
        get { return height; }
        set 
        {
            height = value;
            ApplyBinding();
        }
    }

    public Button Button { get; set; }
    private void ApplyBinding()
    {
        this.Button.SetBinding(Button.HeightProperty, this.Height);
    }

}
Run Code Online (Sandbox Code Playgroud)

AUserControl其中使用我们的DependencyObject实现:

public partial class MyUserControl : UserControl
{
    public MyUserControl()
    {
        InitializeComponent();
    }

    public MyClass MyClass
    {
        get { return (MyClass)GetValue(MyClassProperty); }
        set { SetValue(MyClassProperty, value); }
    }

    // Using a DependencyProperty as the backing store for MyClass.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty MyClassProperty =
        DependencyProperty.Register("MyClass", typeof(MyClass), typeof(MyUserControl), new UIPropertyMetadata(new PropertyChangedCallback(MyClassPropertyChanged)));


    private static void MyClassPropertyChanged(DependencyObject DO, DependencyPropertyChangedEventArgs e)
    {
        var MUC = DO as MyUserControl;
        if (e.NewValue != null)
        {
            var myClass = e.NewValue as MyClass;                
            MUC.MyCanvas.Children.Add(myClass.Button);
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

最后绑定:

<Window x:Class="WpfStackOverflowTempProject.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow"  Width="525"
    DataContext="{Binding RelativeSource={RelativeSource Mode=Self}}"
    xmlns:local="clr-namespace:WpfStackOverflowTempProject"     
    Height="{Binding ElementName=UIContent,Path=MyClass.HeightReplica,Mode=OneWayToSource}"
    >
<local:MyUserControl x:Name="UIContent" >
    <local:MyUserControl.MyClass>
        <local:MyClass Height="{Binding RelativeSource={RelativeSource AncestorType=Window},Path=ActualHeight,Mode=OneWay}" />
    </local:MyUserControl.MyClass>
</local:MyUserControl>
Run Code Online (Sandbox Code Playgroud)

因此,作为上述程序的输出,当Height我们Window进行更改时,它将反映回MyClass组件的 Button element ,就像我们在代码中完成绑定到Button自身一样XAML因此,它 Myclass是逻辑父控件和子元素之间的接口,用于指定公开的属性/绑定 并定义它们与子元素相对应的行为,这些子元素实际上在 UI 上可见,并且MyClass仅像惯用的过滤器一样工作用途。

  • 作者的意思是不同的。尝试执行 &lt;local:MyClass HeightReplica="{Binding ActualHeight}" /&gt; ,您将看到问题所在(它不起作用)。现在从 Freezable 继承你的 MyClass,然后它就可以工作了。 (2认同)