为自定义控件构建逻辑树



我正在处理一个控件,该控件的ObservableCollection是其DependencyProperties之一。此属性被设置为我的控件的DefaultProperty,因此我可以通过构造类似于以下的行将项隐式添加到XAML中的集合:

<MyControl>
    <MyItem/>
    <MyItem/>
    <MyItem/>
</MyControl>

据我所知,WPF引擎在解析XAML时会构建逻辑树。因此,每个MyItem应该是MyControl的逻辑子级。相反,MyControl应该是每个MyItem的逻辑父级。

好吧,显然还有更多。下面是我用来定义上面关系的代码。自定义控件包含ObservableCollectionDependencyProperty,并且由CLR属性支持。

[ContentProperty("Items")]
public class MyControl : Control
{
    public static readonly DependencyProperty ItemsProperty = DependencyProperty.Register(
        "Items", 
        typeof(ObservableCollection<MyItem>), 
        typeof(MyControl), 
        new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.AffectsRender, OnItemsChangedProperty));
    [Category("MyControl")]
    public ObservableCollection<MyItem> Items
    {
        get { return (ObservableCollection<MyItem>)GetValue(ItemsProperty); }
        set { SetValue(ItemsProperty, value); }
    }
    public MyControl() : base()
    {   //Set a new collection per control, but don't destroy binding.
        SetCurrentValue(ItemsProperty, new ObservableCollection<MyItem>());
    }
}

MyItem(它继承了FrameworkContentElement)开始,我尝试访问它的逻辑父级,如下所示:

if (Parent is FrameworkElement)
{    //Re-Render the parent control.
    ((FrameworkElement)Parent).InvalidateVisual();
}

令我惊讶的是,父控件从未被重新渲染。这是因为MyItem.Parent属性为null。为什么会这样?

我如何指示WPF引擎知道MyControl应该是MyItem的逻辑父级?

如果这是针对具有多个图的图表控件,那么您肯定在ItemsControl领域。您可能想看看可以从WPFToolkit或此处列出的其他工具之一构建什么:

https://stackoverflow.com/a/4227432/1869660

至于您的实际问题,如果您确实需要手动将MyItem添加到逻辑树中,则需要调用AddLogicalChild(),例如OnItemsChangedProperty事件中的某个位置。MSDN上有一个例子。

最新更新