In WPF, how can I limit the type of children in a panel?

We want to create a subclass of Canvas that only allows children of a certain type (they must have an intimate knowledge of our subclass and vice versa). However, is there a way to get the panel to accept children of a certain type (or types)?

M

+3
source share
2 answers

The solution we came across was to simply subclass Canvas and then watch the children. If we add that it is not the type that we want, we will immediately remove it and throw an error. Do not stop compile time errors, but do the trick.

, , , "", , . , . - , , , "" ( "" ), , .

, WPF , - , XAML, - . , , , , , - ...

public class TypedCanvas<t> : PanelBase
{
    // Implementation here
}

public class FooCanvas : TypedCanvas<Foo>{}
public class LaaCanvas : TypedCanvas<Laa>{}

... FooCanvas LaaCanvas XAML, .

, TypedPanelBase, .

, , ... , , ! ( , , .)

+2

... .

, . , Panel.InternalChildren:

this.InternalChildren.OfType<MyType>().Do(...);

: , ItemsControl. DataTemplate , . ItemsControl.ItemsPanel - Canvas.

public IEnumerable<string> Items
{
    get;
}

<ItemsControl ItemsSource="{Binding Items}">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Button Content="{Binding}"/>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <Canvas/>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
</ItemsControl>

, ? ? , ContentPresenters Canvas. OnVisualChildrenChanged ( ). Content ContentTemplate null - .

, , , ItemsControl, ContentPresenter:

public class MyItemsControl : ItemsControl
{
    protected override DependencyObject GetContainerForItemOverride()
    {
        return new Button();
    }

    protected override bool IsItemItsOwnContainerOverride(object item)
    {
        return item is Button;
    }
}


    <self:MyItemsControl ItemsSource="{Binding Items}">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <self:MyPanel/>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
    </self:MyItemsControl>

, (Panel.InternalChilder) ( - ), MyPanel :

this.InternalChildren.Cast<Button>()
0

Source: https://habr.com/ru/post/1792148/


All Articles