I have tabcontrol which uses an observable collection of tabitems as itemsource. I dont want the close button for the first tab alone. So i added the style trigger
<Style TargetType="{x:Type TabItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabItem}">
<Grid Background="White">
<Border Name="Border" BorderBrush="#1b9ed2" Margin="6,0,12,0" Background="White">
<ContentPresenter Height="30" x:Name="ContentSite" ContentSource="Header" VerticalAlignment="Bottom" HorizontalAlignment="Center" Margin="5,15,5,-5">
</ContentPresenter>
</Border>
<Button Background="Transparent" BorderBrush="Transparent" Name="TabCloseButton" Click="TabCloseButton_Click" HorizontalAlignment="Right" VerticalAlignment="Bottom" ToolTip="Close" HorizontalContentAlignment="Right" Padding="0">
<materialDesign:PackIcon Kind="Close" Foreground="Gray" HorizontalAlignment="Right"/>
</Button>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="TabIndex" Value="0">
<Setter TargetName="TabCloseButton" Property="Visibility" Value="Collapsed"/>
</Trigger>
......
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="FontSize" Value="12"/>
</Style>
</TabControl.Resources>
It works if i just added the items in xaml
<TabControl Name ="ConnectionsTab">
<TabItem Header="...." TabIndex="0"></TabItem>
<TabItem Header="...." TabIndex="1"></TabItem>
</TabControl>
But it doesn't works when I make the itemsource to the tabcontrol
private ObservableCollection<TabItem> tabItems = new ObservableCollection<TabItem>();
inside constructor
tabItems.Add(new TabItem { Header = "Connections", Content = new ResourceAccountDisplayUserControl(response), TabIndex = 0 });
ConnectionsTab.ItemsSource = tabItems;
I don't know why it does not work. Any idea or code to make it work will be helpful.
First of all, TabIndex
is not the index if your TabItem
inside the TabControl
. So, you need a different way to determine the actual tab position.
If your data source implements IList
, you could for example write a MultiValueConverter
that determines the position of an item within a collection:
public class MyTabItemIndexConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
// TODO: add some validation to avoid unsupported values
var c = (IList)values[1];
return c.IndexOf(values[0]);
}
public object[] ConvertBack(object values, Type[] targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
Side Note: there are probably other ways to determine the index like Determining index of a tabitem .
Then you can use this converter, to store the actual item index somewhere (or use it directly). In this example, I set the TabItem.Tag
property to the item index:
<Window.Resources>
<local:MyTabItemIndexConverter x:Key="tabItemIndexConverter"/>
</Window.Resources>
[...]
<TabControl Name="tabControl1" ItemsSource="{Binding}">
<TabControl.ItemContainerStyle>
<Style TargetType="TabItem">
<Setter Property="Tag">
<Setter.Value>
<MultiBinding Converter="{StaticResource tabItemIndexConverter}">
<Binding />
<Binding ElementName="tabControl1" Path="ItemsSource" />
</MultiBinding>
</Setter.Value>
</Setter>
</Style>
</TabControl.ItemContainerStyle>
[...]
</TabControl>
Now with TabItem.Tag
you have a property that you can actually use in order to implement your trigger logic.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.