Как я могу сделать так, чтобы кнопка отображалась в заголовке WPF TabItem с помощью привязок?
Я создаю пользовательский интерфейс, в котором a TabControl
имеет ряд стандартных TabItem
s с обычными элементами управления WPF в качестве их содержимого. Заголовки, как обычно, просто отображают обычные строки. Однако я хочу, чтобы заголовок последнего элемента содержал Button
вместо обычной строки.
Подчеркну, что я уже знаю, как это делать без привязок. Я хочу сделать это с привязками. В частности, TabControl
привязан к массиву UserControl
s, за исключением последнего объекта, которым является Button
. Это то, Button
что я хочу отображать в заголовке, а не в качестве содержимого последнего TabItem
. (Мне, честно говоря, все равно, каково содержимое последнего TabItem
. Только заголовок.)
Я понимаю DataTemplateSelector
с и StyleSelector
с. Я не могу понять, какая комбинация стилей и шаблонов сделает это за меня. В частности, мне нужно знать, как должны выглядеть Style
и DataTemplate
для последнего элемента, чтобы я мог выбрать их соответствующим образом. Другой код показывать не нужно.
Ответов (3)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 и не хочу загружаться в мою виртуальную машину только для этого. Это должно быть довольно точно.)