C# usercontrol的子依赖项对象上的绑定不起作用

C# usercontrol的子依赖项对象上的绑定不起作用,c#,wpf,binding,user-controls,wpf-controls,C#,Wpf,Binding,User Controls,Wpf Controls,我正在尝试获取一个绑定来处理用户控件的子对象。Xaml如下所示: <MyGrid> <MyColumn ExtendedColumnData="{Binding ColumnToolTipDescriptions}"/> </MyGrid> 但还是没有运气,装订不着火!恼人的是,这似乎很好(如果我将属性添加到网格中): 我对WPF没有太多经验,所以我肯定我遗漏了什么?问题是MyColumnCollection没有继承数据上下文(控件的常规属性不是

我正在尝试获取一个绑定来处理用户控件的子对象。Xaml如下所示:

<MyGrid>
    <MyColumn ExtendedColumnData="{Binding ColumnToolTipDescriptions}"/>
</MyGrid>
但还是没有运气,装订不着火!恼人的是,这似乎很好(如果我将属性添加到网格中):



我对WPF没有太多经验,所以我肯定我遗漏了什么?

问题是
MyColumnCollection
没有继承数据上下文(控件的常规属性不是继承上下文的一部分)。如果没有数据上下文绑定,则绑定将无法工作


要解决此问题,请尝试从
MyColumnCollection
继承
MyColumnCollection
,而不是从
FreezableCollection
(freezable属性是继承上下文的一部分)。

问题在于逻辑树。直接解决方案应(根据您的示例进行调整):


维护控件的逻辑树,以便将dataContext传播到子级。当您调用AddLogicalChild时,它将MyGrid标记为包含逻辑子级,然后将读取LogicalChildren并设置这些子级的dataContext(您可以在其中侦听DataContextChanged事件)。重写LogicalChildren非常重要,因为FrameworkElement没有通过AddLogicalChild和RemovelogicChild调用保留子项列表,这很奇怪。

我已经将其更改为FreezableCollection,但似乎仍然不起作用。我不需要手动设置DataContext,对吗?哦,忘了MyGridColumn。。。您还必须将其基类更改为Freezable。您只需在包含MyGrid的窗口或UserControl上设置DataContext。它必须是具有ColumnToolTipDescriptions属性的对象。
[ContentProperty("Columns")]
public class MyGrid : UserControl
{
    private MyColumnCollection _columns;

    [DesignerSerializationVisibility(DesignerSerializationVisibility.Content), Category("Data")]
    public MyColumnCollection Columns
    {
        get
        {
            if (_columns == null)
                _columns = new MyColumnCollection();

            return _columns;
        }
    }
}

public class MyColumnCollection : ObservableCollection<MyGridColumn>
{
}

public class MyGridColumn : DependencyObject
{
    public object ExtendedColumnData
    {
        get { return (object)GetValue(ExtendedColumnDataProperty); }
        set { SetValue(ExtendedColumnDataProperty, value); }
    }

    public static readonly DependencyProperty ExtendedColumnDataProperty =
        DependencyProperty.Register("ExtendedColumnData", typeof(object), typeof(MyGridColumn), new UIPropertyMetadata(null));
}
<MyColumn ExtendedColumnData="{Binding DataContext.ColumnToolTipDescriptions, ElementName=MyViewName}" />
<MyColumn ExtendedColumnData="{Binding DataContext.ColumnToolTipDescriptions, RelativeSource={RelativeSource AncestorType={x:Type local:MyView}}" />
<MyGrid ExtendedColumnData="{Binding ColumnToolTipDescriptions}">
    <MyColumn />
</MyGrid>
public MyColumnCollection Columns
{
    get
    {
        if (_columns == null)
        {
            _columns = new MyColumnCollection();
            _columns.CollectionChanged += Columns_CollectionChanged;
        }
        return _columns;
    }
}

private void Columns_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
    if (e.NewItems != null)
    {
        foreach (var item in e.NewItems)
        {
            AddLogicalChild(item);
        }
    }
    if (e.OldItems != null)
    {
        foreach (var item in e.OldItems)
        {
            RemoveLogicalChild(item);
        }
    }
    // not sure about Action == reset
}

protected override IEnumerator LogicalChildren
{
    get
    {
        return _columns == null ? null : _columns.GetEnumerator();
    }
}