Добавьте дополнительные элементы при использовании ItemsSource
В проекте, который я строю, у меня есть TabControl
в котором я хочу отобразить ряд вкладок через ItemsSource
, Мне также нужно иметь несколько "обзорных" вкладок в начале TabControl
, который не может быть расположен в ItemsSource
,
Что является лучшим способом для достижения этой цели, единственный способ, о котором я могу думать, - это иметь мои обзорные вкладки в моем XAML и просто добавлять элементы вкладок вручную через код вместо использования ItemSource
это лучший способ сделать это.
4 ответа
Ты можешь использовать CompositeCollection
( MSDN) для достижения этой цели:
<Window.Resources>
<CollectionViewSource x:Key="ExistingTabs" Source="{Binding ExistingTabs}"/>
</Window.Resources>
<TabControl>
<TabControl.ItemsSource>
<CompositeCollection>
<TabItem>SpecialItem</TabItem>
<CollectionContainer Collection="{Binding Source={StaticResource ExistingTabs}}"/>
</CompositeCollection>
</TabControl.ItemsSource>
</TabControl>
Для тех, кто ищет способ использования HeaderTemplate / ContentTemplate с CollectionContainer:
Свойство First Add Type в ViewModel
public Type Type { get { return this.GetType(); } }
Используйте Style.Triggers, чтобы установить HeaderTemplate / ContentTemplate для динамических вкладок, определенных свойством Type
<Window x:Class="TabDemo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:TabDemo"
xmlns:vm="clr-namespace:TabDemo.ViewModel"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525"
d:DataContext="{d:DesignInstance vm:TabViewModel}">
<Window.Resources>
<CollectionViewSource x:Key="ExistingTabs" Source="{Binding ExistingTabs}"/>
<DataTemplate x:Key="TemplateForTheHeader" DataType="{x:Type vm:TabViewModel}">
<TextBlock Text="{Binding Title}"/>
</DataTemplate>
<DataTemplate x:Key="TemplateForTheContent" DataType="{x:Type vm:TabViewModel}">
<DockPanel>
<DataGrid ItemsSource="{Binding Data}"></DataGrid>
</DockPanel>
</DataTemplate>
<Style x:Key="TabItemStyle" TargetType="TabItem">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=Type}" Value="{x:Type vm:TabViewModel}">
<Setter Property="HeaderTemplate" Value="{StaticResource TemplateForTheHeader}" />
<Setter Property="ContentTemplate" Value="{StaticResource TemplateForTheContent}" />
</DataTrigger>
</Style.Triggers>
</Style>
</Window.Resources>
<Grid>
<TabControl Grid.Row="1" ItemContainerStyle="{StaticResource TabItemStyle}">
<TabControl.ItemsSource>
<CompositeCollection>
<TabItem Header="Fixed Header">
<TabItem.Content>
<TextBlock Text="Fixed Content"/>
</TabItem.Content>
</TabItem>
<CollectionContainer Collection="{Binding Source={StaticResource ExistingTabs}}"/>
</CompositeCollection>
</TabControl.ItemsSource>
</TabControl>
</Grid>
</Window>
Ссылка на ответ Anderson Imes: /questions/12333918/wpf-tabcontrol-i-datatemplates/12333923#12333923
Вы можете использовать CompositeCollection. Как добавить общий элемент в ComboBox, связанный с коллекцией в WPF
<TabControl>
<TabControl.ItemsSource>
<CompositeCollection>
<TabItem Header="extra tab item"> //Not bound
<TextBox>something</TextBox>
</TabItem>
<CollectionContainer x:Name="cc"/>
</CompositeCollection>
</TabControl.ItemsSource>
</TabControl>
Код позади:
cc.Collection=yourObservableCollection
К сожалению, вы не можете смешивать привязку ItemsSource с явно добавленными объектами коллекции Items. Таким образом, у вас есть два варианта: либо добавить фиксированные элементы, а затем элементы из вашего связанного списка вручную в коллекцию Items или связать ItemsSource с коллекцией, которая содержит как набор фиксированных объектов, так и элементы вашей связанной коллекции. В любом случае, самая большая проблема, вероятно, связана с обновлением при изменении ваших данных - убедитесь, что нужные элементы удалены / добавлены, а пользовательский интерфейс обновлен правильно.