当父元素绑定成功时,为什么将子元素绑定到另一个元素会失败?

4

假设我有两个类可以引用第三个UI对象(在这个例子中是一个按钮)。

此外,父类可以包含子类的元素。

如果它们都绑定到相同的控件,并以相同的方式进行绑定,则子类将失败但父类将成功。

这是WPF中的错误吗?


父类:

class MyFrameworkElement : FrameworkElement
{
    // A depenedency property that will contain a child element sub-element
    private static readonly DependencyProperty ChildElementProperty =
                    DependencyProperty.Register("ChildElement",
                    typeof(MyChildElement),
                    typeof(MyFrameworkElement),
                    new PropertyMetadata());

    [Category("ChildProperties")]
    public MyChildElement ChildElement
    {
        set { SetValue(ChildElementProperty, value); }
        get { return (MyChildElement)GetValue(ChildElementProperty); }
    }


    // Now, a reference to some other control, in this case we will bind a button to it!
    public UIElement ButtonReferenceInParent
    {
        get { return (UIElement)GetValue(ButtonReferenceInParentProperty); }
        set { SetValue(ButtonReferenceInParentProperty, value); }
    }

    // Using a DependencyProperty as the backing store for ButtonReferenceInParent.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty ButtonReferenceInParentProperty =
        DependencyProperty.Register("ButtonReferenceInParent", typeof(UIElement), typeof(MyFrameworkElement), new UIPropertyMetadata(null));

然后孩子:

public class MyChildElement : FrameworkElement
{
    public UIElement ButtonReferenceInChild
    {
        get { return (UIElement)GetValue(ButtonReferenceInChildProperty); }
        set { SetValue(ButtonReferenceInChildProperty, value); }
    }

    public static readonly DependencyProperty ButtonReferenceInChildProperty =
        DependencyProperty.Register("ButtonReferenceInChild", typeof(UIElement), typeof(MyChildElement), new UIPropertyMetadata(null));
}

好的 -

现在假设我要这样将它们添加到我的XAML文件中:

<Grid>
    <my:MyFrameworkElement x:Name="ParentName" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" ButtonReferenceInParent="{Binding ElementName=buttonisme}">
        <my:MyFrameworkElement.ChildElement>
            <my:MyChildElement x:Name="ChildName" ButtonReferenceInChild="{Binding ElementName=buttonisme}"/>
        </my:MyFrameworkElement.ChildElement>
    </my:MyFrameworkElement>
    
    <Button x:Name="buttonisme" Click="buttonisme_Click" />
</Grid>

为什么我使用完全相同的符号,绑定在父元素上可以正常工作,但是在子元素上失败了?


这是我的测试代码...

     Console.WriteLine("Parent button reference is {0}", ParentName.ButtonReferenceInParent);

        if (ChildName.ButtonReferenceInChild == null)
        {
            Console.WriteLine("Child button reference is null!");
        } 
        else
        {
            Console.WriteLine("Child button is {0}", ChildName.ButtonReferenceInChild);
        }

以下是测试结果...

父级按钮引用为System.Windows.Controls.Button

子级按钮引用为空!

2个回答

7
长话短说,微软不希望您在没有进行一些“管道”工作的情况下从FrameworkElement派生。

仅仅进行派生会破坏逻辑树,而这是按元素名称进行绑定时使用的。

您可能还需要修建可视化树,并重载框架元素的排列/测量部分。(我们在此示例中不这样做,因为我们不是可视化的。)

在这种特定情况下,我们需要将您的对象的任何子项添加到逻辑树中,否则就会破坏绑定子元素的能力。

有人解决了这个问题的好例子在这里。

关于覆盖逻辑树的信息在这里。

无论如何,修复这个简单示例所需的代码只依赖于逻辑树(因为子对象实际上并不是可视化的)。

        private static readonly DependencyProperty ChildElementProperty =
                    DependencyProperty.Register("ChildElement",
                    typeof(MyChildElement),
                    typeof(MyFrameworkElement),
                    new PropertyMetadata(OnChildElementChanged));

    private static void OnChildElementChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        MyFrameworkElement control = d as MyFrameworkElement;

        if (e.OldValue != null)
        {
            control.RemoveLogicalChild(e.OldValue);
        }

        control.AddLogicalChild(e.NewValue);
    }

-1

首先,当您像这样设置xaml时:

<my:MyFrameworkElement x:Name="ParentName" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" ButtonReferenceInParent="{Binding ElementName=buttonisme}"/>
<my:MyChildElement x:Name="ChildName" ButtonReferenceInChild="{Binding ElementName=buttonisme}"/>

它有效。我这样做是因为我怀疑在绑定中使用的元素名称进行可视树向上遍历搜索。

我仍在弄清楚如何在您的嵌套场景中成功绑定。但也许这可以给您一些提示...


那个限制听起来有些奇怪。我经常绑定同一级别的东西(在不同的分支上),比如将一个单选按钮组中的单选按钮与另一个子分组的复选框绑定。这可能与子元素不是UIElement有关吗?...但是更改也没有解决问题。 - Jeremy White

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接