当父成功时将子元素绑定到另一个元素时,为什么绑定失败?
-
12-12-2019 - |
题
说我有两个可以引用第三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
子按钮引用为null!
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));
}
<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
子按钮引用为null!
解决方案
很长的问题是很长的问题是微软不希望你从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);
}
. 其他提示
首先,当您设置这样的XAML时:
<my:MyFrameworkElement x:Name="ParentName" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" ButtonReferenceInParent="{Binding ElementName=buttonisme}"/>
<my:MyChildElement x:Name="ChildName" ButtonReferenceInChild="{Binding ElementName=buttonisme}"/>
.
它有效。我这样做是因为我怀疑向上遍历横幅搜索你在绑定中使用的元素名称。
我仍然弄清楚绑定如何在嵌套场景中成功。但也许这可能会给你一些提示......
不隶属于 StackOverflow