質問

I have a ToolBar with a bound ItemsSource, I am using DataTemplateSelector to determine the DataTemplate at runtime (i.e Button / ToggleButton).

I want to add a Separator DataTemplate, how do I do that?

役に立ちましたか?

解決

The ToolBar is an ItemsControl, so it wants to "wrap" the items defined in Items/ItemsSource with a "container". The container is a UIElement that can be used to display the item. In the case of a ListBox for example, the container is a ListBoxItem. If an item is of the proper type, then it can also be it's own container.

This setup allows you to pass a list of strings to a ListBox and have it display property and support selection, keyboard navigation, styling, etc.

In the case of the ToolBar, it really expects it's items to already be a container (i.e. a UIElement). If the item is not a UIElement, then it will wrap it with a ContentPresenter.

Now, the DataTemplateSelecter is used by the container to determine how to display it's item. But you need the item to be a Button, ToggleButton, Separator, etc. You are suggesting that you should add the container in the DataTemplate displayed by the container.

There is also the problem of Styles, which can be seen with this simple example:

<Window x:Class="TestWPF.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:system="clr-namespace:System;assembly=mscorlib" Title="Main"
        Height="500" Width="500">
    <DockPanel LastChildFill="False">
        <ToolBar DockPanel.Dock="Top">
            <ToolBar.ItemTemplate>
                <DataTemplate>
                    <Button Content="{Binding}" />
                </DataTemplate>
            </ToolBar.ItemTemplate>
            <system:String>Test1</system:String>
            <system:String>Test2</system:String>
        </ToolBar>
        <ToolBar DockPanel.Dock="Top">
            <Button>Test1</Button>
            <Button>Test2</Button>
        </ToolBar>
    </DockPanel>
</Window>

The buttons in the ToolBar on top will render with the same look as if they were not in the ToolBar. The buttons in the ToolBar on the bottom will get a "toolbar" look. The same goes for Separators.

You can manually apply the Style like so:

<Window x:Class="TestWPF.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:system="clr-namespace:System;assembly=mscorlib" Title="Main"
        Height="500" Width="500">
    <DockPanel LastChildFill="False">
        <ToolBar DockPanel.Dock="Top">
            <ToolBar.ItemTemplate>
                <DataTemplate>
                    <Button Content="{Binding}"
                        Style="{StaticResource {x:Static ToolBar.ButtonStyleKey}}" /> <!-- Add the Style attribute -->
                </DataTemplate>
            </ToolBar.ItemTemplate>
            <system:String>Test1</system:String>
            <system:String>Test2</system:String>
        </ToolBar>
        <ToolBar DockPanel.Dock="Top">
            <Button>Test1</Button>
            <Button>Test2</Button>
        </ToolBar>
    </DockPanel>
</Window>

You would have the same problem with Separators. So you'd need to manually apply the Style like so:

<DataTemplate x:Key="MySeparatorTemplate">
    <Separator Style="{StaticResource {x:Static ToolBar.SeparatorStyleKey}}" />
</DataTemplate>

You should be able to use the DataTemplate above in your DataTemplateSelector, just like you do with buttons.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top