Добавление дополнительных элементов при использовании 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:
Сначала добавьте свойство Type в ViewModel
public Type Type { get { return this.GetType(); } }Используйте Стиль.Триггеры для установки 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>Ссылка на Ответ Андерсона Имеса : https://stackoverflow.com/a/1348369/1196637
Вы можете использовать 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 к коллекции, содержащей как набор фиксированных объектов, так и элементы связанной коллекции. В любом случае самая большая проблема, вероятно, связана с обновлением при изменении данных - убедитесь, что правильные элементы удаляются/добавляются, а пользовательский интерфейс обновляется правильно.
Comments