WPF:绑定无法找到源

时间:2011-11-30 14:07:35

标签: wpf binding custom-controls

我尝试创建自己的ContentControl,它来自Control,以完全理解黑暗的wpf树概念。目前,我刚刚实现了ContentControl的逻辑部分(Content)。

我的代码背后:

[ContentProperty("Content")]
public class MyContentControl : Control
{
    public MyContentControl()
    {

    }

    public Object Content
    {
        get { return (Object)GetValue(ContentProperty); }
        set { SetValue(ContentProperty, value); }
    }

    public static readonly DependencyProperty ContentProperty =
        DependencyProperty.Register("Content", typeof(Object), typeof(MyContentControl), new UIPropertyMetadata());

}

XAML:

<StackPanel x:Name="stackPanel">
    <TextBlock Visibility="Collapsed" x:Name="textBlock" Text="Hello World"/>
    <ContentControl>
        <TextBlock Background="LightBlue" Text="{Binding Text, ElementName=textBlock}"/>
    </ContentControl>
    <local:MyContentControl>
        <TextBlock Text="{Binding Text, ElementName=textBlock}"/>
    </local:MyContentControl>
</StackPanel>

我收到了以下绑定错误:

  

System.Windows.Data错误:4:找不到引用'ElementName = textBlock'的绑定源。 BindingExpression:路径=文本;的DataItem = NULL; target元素是'TextBlock'(Name =''); target属性是'Text'(类型'String')

就像内部TextBlock无法在逻辑树中上升并找到它应该绑定的原始文本块。我无法将myContentControl设置为Content对象的父级。

任何想法?

感谢您的时间。

纳斯

2 个答案:

答案 0 :(得分:4)

相关问题:Binding ElementName. Does it use Visual Tree or Logical Tree

您想要的绑定是不可能的,因为MyContentControl的相同实例理论上可以在应用程序中的其他位置使用,其中元素“textBlock”不在范围内。

如果你想做这种类型的绑定,你可以改用资源:

xmlns:clr="clr-namespace:System;assembly=mscorlib"

<StackPanel>
    <StackPanel.Resources>
        <clr:String x:Key="MyText">Hanky Panky</clr:String>
    </StackPanel.Resources>
    <TextBlock Text="{StaticResource MyText}" />

    <ContentControl>
        <TextBlock Text="{Binding Source={StaticResource MyText}}" />
    </ContentControl>
</StackPanel>

答案 1 :(得分:2)

当ContentChanged和绑定正确应用时,我必须应用FrameworkElement.AddLogicalChild和FrameworkElement.RemoveLogicalChild(使用WPF检查器验证)。

所以这一切都与LogicalTree有关(也许xaml的名称范围是从逻辑父级继承的)。当MyContentControl.AddLogicalChild(TextBlock)被调用时,MyContentControl中的TextBlock将MyContentControl作为Parent。

我的代码:

[ContentProperty("Content")]
public class MyContentControl : Control
{
    public MyContentControl()
    {
        Content = new UIElementCollection(this, this);
    }


    public Object Content
    {
        get { return (Object)GetValue(ContentProperty); }
        set { SetValue(ContentProperty, value); }
    }

    public static readonly DependencyProperty ContentProperty =
        DependencyProperty.Register("Content", typeof(Object), typeof(MyContentControl), new UIPropertyMetadata(new PropertyChangedCallback(OnContentChanged)));

    public static void OnContentChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        MyContentControl c = (MyContentControl)d;

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

        c.AddLogicalChild(e.NewValue);
    }

    protected override System.Collections.IEnumerator LogicalChildren
    {
        get
        {
            List<Object> l = new List<object>();
            if (Content != null)
                l.Add(Content);

            return l.GetEnumerator();
        }
    }
}