Home > database >  How to implement a Custom ItemsControl with pre-built items?
How to implement a Custom ItemsControl with pre-built items?

Time:02-15

I want to create a custom control that acts like a ToolBar control but contains pre-built elements in addition to those provided by the user.

As an example, with the code below I need a tool bar that contains predefined elements then the two user provided buttons:

<MyToolBar>
    <Button>User button 1</Button>
    <Button>User button 2</Button>
</MyToolBar>

Which would then be equivalent to:

<ToolBar>
    <Button>Predefined button 1</Button>
    <Button>Predefined button 2</Button>
    <Button>User button 1</Button>
    <Button>User button 2</Button>
</ToolBar>

I have tried inheriting ToolBar class and specify a CompositeCollection as ToolBar.ItemSource, however it fails, throwing

Cannot find governing FrameworkElement or FrameworkContentElement for target element

<!-- Wrong Code -->
<Style TargetType="{x:Type local:MyToolBar}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type local:MyToolBar}">
                <ToolBar>
                    <ToolBar.ItemsSource>
                        <CompositeCollection>
                            <CollectionContainer Collection="{Binding ItemsSource,RelativeSource={RelativeSource TemplatedParent}}" />
                            <Button>Predefined button 1</Button>
                            <Button>Predefined button 2</Button>
                        </CompositeCollection>
                    </ToolBar.ItemsSource>
                </ToolBar>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

CodePudding user response:

Define a read-only enter image description here

CodePudding user response:

Based on this question, it appear that the binding on CollectionContainer.Collection do not update the container content when the source content change.
You have to use a CollectionViewSource has a proxy:

<Style x:Key="MyToolBarStyle" TargetType="{x:Type ToolBar}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type ToolBar}">
                <ToolBar>
                    <ToolBar.Resources>
                        <CollectionViewSource x:Key="TemplateItems" Source="{TemplateBinding ItemsSource}" />
                    </ToolBar.Resources>
                    <ToolBar.ItemsSource>
                        <CompositeCollection>
                            <Button>Predefined button 1</Button>
                            <Button>Predefined button 2</Button>
                            <CollectionContainer Collection="{Binding Source={StaticResource TemplateItems}}" />
                        </CompositeCollection>
                    </ToolBar.ItemsSource>
                </ToolBar>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>
  •  Tags:  
  • wpf
  • Related