当绑定一个子元素,当父成功的另一要素为什么绑定失败? [英] Why does binding fail when binding a child element to another element when the parent succeeds?

查看:124
本文介绍了当绑定一个子元素,当父成功的另一要素为什么绑定失败?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

说我有可以引用的第三UI对象(在本实施例的一个按钮)两个类。

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

如果他们都被绑定到相同的控制,以同样的方式,的的孩子会失败,但父母成功。

这是在WPF中的错误?


父:

 类MyFrameworkElement:FrameworkElement的
{
    //将包含一个子元素的子元素A depenedency财产
    私人静态只读的DependencyProperty ChildElementProperty =
                    DependencyProperty.Register(是childElement
                    typeof运算(MyChildElement)
                    typeof运算(MyFrameworkElement)
                    新PropertyMetadata());

    [类别(ChildProperties)
    公共MyChildElement是childElement
    {
        集合{的SetValue(ChildElementProperty,价值); }
        {返回(MyChildElement)的GetValue(ChildElementProperty); }
    }


    //现在,参考一些其他控制,在这种情况下,我们将一个按钮绑定到它!
    公众的UIElement ButtonReferenceInParent
    {
        {返回(UIElement的)的GetValue(ButtonReferenceInParentProperty); }
        集合{的SetValue(ButtonReferenceInParentProperty,价值); }
    }

    //使用的DependencyProperty作为后备存储ButtonReferenceInParent。这使得动画制作,造型,绑定等..
    公共静态只读的DependencyProperty ButtonReferenceInParentProperty =
        DependencyProperty.Register(ButtonReferenceInParent的typeof(UIElement的)的typeof(MyFrameworkElement),新UIPropertyMetadata(空));
 


和那么孩子:

 公共类MyChildElement:FrameworkElement的
{
    公众的UIElement ButtonReferenceInChild
    {
        {返回(UIElement的)的GetValue(ButtonReferenceInChildProperty); }
        集合{的SetValue(ButtonReferenceInChildProperty,价值); }
    }

    公共静态只读的DependencyProperty ButtonReferenceInChildProperty =
        DependencyProperty.Register(ButtonReferenceInChild的typeof(UIElement的)的typeof(MyChildElement),新UIPropertyMetadata(空));
}
 

确定 -

现在说我将它们添加到我的XAML是这样的:

 <电网>
    <我:MyFrameworkElement X:名称=ParentName的Horizo​​ntalAlignment =拉伸VerticalAlignment =拉伸ButtonReferenceInParent ={结合的ElementName = buttonisme}>
        <我:MyFrameworkElement.ChildElement>
            <我:MyChildElement X:名称=ChildNameButtonReferenceInChild ={结合的ElementName = buttonisme}/>
        < /我:MyFrameworkElement.ChildElement>
    < /我:MyFrameworkElement>

    <按钮X:名称=buttonisme点击=buttonisme_Click/>
< /网格>
 

为什么父的绑定工作,但随后在孩子失败了,当我使用的是完全相同的符号?


下面是我的测试code ...

  Console.WriteLine(父键引用{0},Pa​​rentName.ButtonReferenceInParent);

        如果(ChildName.ButtonReferenceInChild == NULL)
        {
            Console.WriteLine(儿童按钮引用为空!);
        }
        其他
        {
            Console.WriteLine(子键是{0},ChildName.ButtonReferenceInChild);
        }
 

这里是测试结果...

  

父键引用System.Windows.Controls.Button

     

子按钮引用为空!

解决方案

简短的回答很长的问题是,微软并没有指望你自FrameworkElement派生没有做一个小的管道。

只是在做推导,打破它是由元素名做绑定时所使用的逻辑树。

您可能也有梅花了可视化树,和过载框架元件的排列/措施部分。 (我们不这样做,在这里,因为我们没有视觉的例子。)

在这种特殊情况下,我们需要你的对象的所有子添加到逻辑树或打破绑定子元素的能力。

人谁解决了一个很好的例子,这是这里

上重写逻辑树的信息,这里

不管怎么说,要解决这个简单的例子仅仅依靠逻辑树所需的code(作为子对象是不是真正的视觉享受。)

添加此功能,改变依赖属性使绑定工作。

 私有静态只读的DependencyProperty ChildElementProperty =
                    DependencyProperty.Register(是childElement
                    typeof运算(MyChildElement)
                    typeof运算(MyFrameworkElement)
                    新PropertyMetadata(OnChildElementChanged));

    私有静态无效OnChildElementChanged(DependencyObject的研发,DependencyPropertyChangedEventArgs E)
    {
        MyFrameworkElement控制= D为MyFrameworkElement;

        如果(e.OldValue!= NULL)
        {
            control.RemoveLogicalChild(e.OldValue);
        }

        control.AddLogicalChild(e.NewValue);
    }
 

Say I have two classes that can reference a third UI object (in this example a button).

In addition, the parent class can contain an element of the child class.

If they both are bound to the same control, the same way, the child will fail but the parent succeed.

Is this a bug in WPF?


The parent :

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));


And then the child :

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));
}

OK -

Now say I Add them to my XAML like this :

<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>

Why does the binding work on the parent but then fail on the child, when I am using the EXACT same notation?


Here is my test code...

     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);
        }

And here is the test result...

Parent button reference is System.Windows.Controls.Button

Child button reference is null!

解决方案

The short answer to a long question is that Microsoft doesn't expect you to derive from FrameworkElement without doing a little plumbing.

Just doing derivation, breaks the logical tree which is used when doing binding by element name.

You probably also have to plum up the visual tree, and overload the arrange/measure parts of framework element. (We don't do that here as we aren't visual in the example.)

In this specific case we need to add any children of your object to the logical tree or break the ability to bind child elements.

A good example of someone who solved this is here

Information on overriding the logical tree is here

Anyways, the code needed to fix this SIMPLE example only relied on the logical tree (as the child object isn't really visual.)

Adding this function and changing the dependency property makes the binding work.

        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);
    }

这篇关于当绑定一个子元素,当父成功的另一要素为什么绑定失败?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆