C# usercontrol的子依赖项对象上的绑定不起作用
我正在尝试获取一个绑定来处理用户控件的子对象。Xaml如下所示: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没有继承数据上下文(控件的常规属性不是
<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();
}
}