Как я могу сделать так, чтобы кнопка отображалась в заголовке WPF TabItem с помощью привязок?

Я создаю пользовательский интерфейс, в котором a TabControl имеет ряд стандартных TabItem s с обычными элементами управления WPF в качестве их содержимого. Заголовки, как обычно, просто отображают обычные строки. Однако я хочу, чтобы заголовок последнего элемента содержал Button вместо обычной строки.

Подчеркну, что я уже знаю, как это делать без привязок. Я хочу сделать это с привязками. В частности, TabControl привязан к массиву UserControl s, за исключением последнего объекта, которым является Button . Это то, Button что я хочу отображать в заголовке, а не в качестве содержимого последнего TabItem . (Мне, честно говоря, все равно, каково содержимое последнего TabItem . Только заголовок.)

Я понимаю DataTemplateSelector с и StyleSelector с. Я не могу понять, какая комбинация стилей и шаблонов сделает это за меня. В частности, мне нужно знать, как должны выглядеть Styleи DataTemplateдля последнего элемента, чтобы я мог выбрать их соответствующим образом. Другой код показывать не нужно.

Ответов (3)

Я сам разобрался. Я новичок в WPF / XAML, и я только что понял, что в случае ItemsControl, такого как TabControl, DataTemplate выкладывает содержимое каждого элемента, но ничего не говорит об общем макете самого элемента, который управляется его ControlTemplate. Теперь я понимаю, что мне вообще не нужен DataTemplateSelector, просто стиль для последнего элемента, например:

            <Style x: Key = "buttonStyle" TargetType = "TabItem">
                <Setter Property = "Template">
                    <Setter.Value>
                        <ControlTemplate TargetType = "TabItem">
                            <Граница>
                                <ContentPresenter
                                    Маржа = "4,1,0,1"
                                    Content = "{Binding}"
                                    ContentSource = "Заголовок">
                                </ContentPresenter>
                            </Border>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>


Первое, что я хотел бы попробовать, это установить стиль последнего элемента TabItem . В стиле, если вы привязываете свойство Header к свойству Content , в результате чего кнопка должна отображаться в заголовке TabItems. Тогда вам понадобится DataTemplate, невидимый для элемента, чтобы вы не видели его в области содержимого вкладки.

Если это не сработает, вам может потребоваться создать новый ControlTemplate для элемента вкладки. Шаблон по умолчанию выглядит так:

<Grid SnapsToDevicePixels="true">
<Border Name="Bd" Padding="{TemplateBinding Padding}" BorderBrush="{TemplateBinding BorderBrush}" Background="{TemplateBinding Background}" BorderThickness="1,1,1,0">
    <ContentPresenter Name="Content" 
            ContentSource="Header" 
            SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" 
            RecognizesAccessKey="true" 
            HorizontalAlignment="{Binding Path=HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" 
                VerticalAlignment="{Binding Path=VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" />
</Border>

Единственное, что вам нужно будет изменить, это ContentSource с Header на Content . Вы должны создать копию оригинала, чтобы сделать это, потому что в противном случае вы упустите все соответствующие триггеры. Вы можете найти оригинал, используя расширение BAML viewer для Reflector. Или вы можете получить оригинал в Blend, если он у вас есть.

Есть еще один способ сделать это еще лучше.

<TabControl>
    <TabControl.ItemsSource>
        <CompositeCollection>
        <CollectionContainer Collection="{StaticResource items}" />
            <TabItem>
            <TabItem.Template>
                    <ControlTemplate>
                        <Border Name="PART_Header" Margin="4,0,1,1">                                    
                            <Button Click="AddTicket">Add Ticket</Button>
                    </Border>
                </ControlTemplate>
                </TabItem.Template>
            </TabItem>
        </CompositeCollection>
    </TabControl.ItemsSource>
</TabControl>

(Обратите внимание, что все это было сделано полностью из памяти. Я использую Mac и не хочу загружаться в мою виртуальную машину только для этого. Это должно быть довольно точно.)