I'm quite new in C# and WPF so please forgive in case of stupid questions :-). I would like to change dynamically the selected tab color property from the back code. I've found few solutions but only for static color change. Dynamic color change of non-selected tab is done. Please see the code:
XAML:
<TabControl x:Name="tabSections" Margin="0,400,0,20" Width="1348" BorderBrush="{x:Null}" FontSize="16" FontWeight="Bold" Visibility="Visible" TabStripPlacement="Top" Cursor="Hand" SelectionChanged="tabSections_SelectionChanged">
<TabControl.Background>
<SolidColorBrush Color="#FF464646" Opacity="1"/>
</TabControl.Background>
<TabItem x:Name="tabSect1" Width="168" Height="30" Header="Section 1">
</TabItem>
<TabItem x:Name="tabSect2" Width="168" Height="30" Header="Section 2">
</TabItem>
<TabItem x:Name="tabSect3" Width="168" Height="30" Header="Section 3">
</TabItem>
<TabItem x:Name="tabSect4" Width="168" Height="30" Header="Section 4">
</TabItem>
<TabItem x:Name="tabSect5" Width="168" Height="30" Header="Section 5">
</TabItem>
<TabItem x:Name="tabSect6" Width="168" Height="30" Header="Section 6">
</TabItem>
<TabItem x:Name="tabSect7" Width="168" Height="30" Header="Section 7">
</TabItem>
<TabItem x:Name="tabSect8" Width="168" Height="30" Header="Section 8">
</TabItem>
</TabControl>
C#:
for (int i = 0; i < SectionCount; i )
{
if (TabsColors[i])
{
TabBrushes[i] = Brushes.Orange;
}
else
{
TabBrushes[i] = Brushes.LightGreen;
}
}
for (int j = SectionCount; j < 8; j )
{
TabBrushes[j] = Brushes.DarkGray;
}
tabSect1.Background = TabBrushes[0];
tabSect2.Background = TabBrushes[1];
tabSect3.Background = TabBrushes[2];
tabSect4.Background = TabBrushes[3];
tabSect5.Background = TabBrushes[4];
tabSect6.Background = TabBrushes[5];
tabSect7.Background = TabBrushes[6];
tabSect8.Background = TabBrushes[7];
Thank you for help in advance. Have a nice day.
CodePudding user response:
You can always get the selected item of a Selector control by referencing its SelectedItem property.
To use a Style, simply reference the Brush as a dynamic resource and change it from e.g., your code-behind:
MainWindow.xaml
<Window>
<Window.Resources>
<SolidColorBrush x:Key="SelectedItemBackgroundBrush"
Color="Red" />
<Style TargetType="{x:Type TabItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabItem}">
<Border x:Name="Border"
Margin="0,0,-4,0"
CornerRadius="2,12,0,0"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<ContentPresenter x:Name="ContentSite"
VerticalAlignment="Center"
HorizontalAlignment="Center"
ContentSource="Header"
Margin="12,2,12,2"
RecognizesAccessKey="True" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver"
Value="True">
<Setter Property="Background"
Value="LightGray" />
</Trigger>
<Trigger Property="IsSelected"
Value="True">
<Setter Property="Panel.ZIndex"
Value="100" />
<Setter Property="Background"
Value="{DynamicResource SelectedItemBackgroundBrush}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
</Window>
MainWindow.xaml.cs
this.Resources["SelectedItemBackgroundBrush"] = Brushes.GreenYellow;
When you need to acces each element of a collection, you should never access it explicitly. Rather would you iterate over the collection:
for (int tabItemIndex = 0; tabItemIndex < this.tabSections.Items.Count; tabItemindex )
{
var tabItem = this.tabSections.Items[tabItemIndex] as TabItem;
tabItem.Background = tabItem.IsSelected
? Brushes.Red
: this.TabBrushes[tabItemIndex];
}
// Alternative way to change the color of the selected item
var selectedTabItem = this.tabSections.SelectedItem as TabItem;
selectedTabItem.Background = this.TabBrushes[tabItemIndex];
CodePudding user response:
First I would like to thank you @BionicCode for help.
The mistake I've made from the beginning was the trigger declaration order in XAML.
The below example first declares selected tab property, then enabled tab property which overwrites, so the selected property have no chance to be seen.
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="border" Value="LightGray" />
</Trigger>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="border" Property="Background" Value="{DynamicResource SelectedItemBackgroundBrush}" />
<Setter Property="Foreground" Value="Black"/>
<Setter Property="FontWeight" Value="Bold"/>
<Setter Property="FontSize" Value="16"/>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="border" Property="Background" Value="#FF464646" />
<Setter Property="Foreground" Value="Gray"/>
<Setter Property="FontWeight" Value="UltraLight"/>
</Trigger>
<Trigger Property="IsEnabled" Value="True">
<Setter TargetName="border" Property="Background" Value="{DynamicResource EnabledItemBackgroundBrush}" />
<Setter Property="Foreground" Value="Black"/>
<Setter Property="FontWeight" Value="UltraLight"/>
</Trigger>
</ControlTemplate.Triggers>
The correct order is (selected property after enabled property):
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="border" Value="LightGray" />
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="border" Property="Background" Value="#FF464646" />
<Setter Property="Foreground" Value="Gray"/>
<Setter Property="FontWeight" Value="UltraLight"/>
</Trigger>
<Trigger Property="IsEnabled" Value="True">
<Setter TargetName="border" Property="Background" Value="{DynamicResource EnabledItemBackgroundBrush}" />
<Setter Property="Foreground" Value="Black"/>
<Setter Property="FontWeight" Value="UltraLight"/>
</Trigger>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="border" Property="Background" Value="{DynamicResource SelectedItemBackgroundBrush}" />
<Setter Property="Foreground" Value="Black"/>
<Setter Property="FontWeight" Value="Bold"/>
<Setter Property="FontSize" Value="16"/>
</Trigger>
</ControlTemplate.Triggers>
Have a good day!
