I have the following style:
<SolidColorBrush x:Key="TabPanelBorderBrush" Color="#007ACC"/>
<Style TargetType="{x:Type local:MetroTabControl}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:MetroTabControl}">
<Grid>
<Grid KeyboardNavigation.TabNavigation="Local" SnapsToDevicePixels="True">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid>
<ScrollViewer x:Name="ScrollViewer" VerticalScrollBarVisibility="Disabled" HorizontalScrollBarVisibility="Hidden" Style="{DynamicResource TabPanelScrollViewer}">
<TabPanel x:Name="HeaderPanel" IsItemsHost="True" Panel.ZIndex="1" KeyboardNavigation.TabIndex="1"/>
</ScrollViewer>
<Button x:Name="AddTabItem" Content="" Style="{DynamicResource TabControlButton}" HorizontalAlignment="Right" VerticalAlignment="Top"/>
</Grid>
<Border Grid.Row="1" x:Name="TabPanelBorder" Background="Transparent">
<Rectangle x:Name="TabPanelBorderRectangle" Fill="{DynamicResource TabPanelBorderBrush}" Height="2"/>
</Border>
<Border Grid.Row="2" Background="{StaticResource TabControlBackground}"/>
<ContentPresenter Grid.Row="2" Name="PART_SelectedContentHost" ContentSource="SelectedContent"/>
</Grid>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I want to bind the TabPanelBorderRectangle's Fill
color to the TabControl
's SelectedItem
's Foreground
.
So I wrote the following:
<Rectangle x:Name="TabPanelBorderRectangle" Fill="{Binding SelectedItem.Foreground, RelativeSource={RelativeSource Mode=TemplatedParent}}" Height="2"/>
And it works.
Now, I have another style, BasedOn
the above.
In the BasedOn
style, I want to put the line above, but when I do it doesnt work.
Here's my BasedOn Style:
<Style x:Key="CustomizedMetroTabControl" TargetType="{x:Type local:MetroTabControl}" BasedOn="{StaticResource {x:Type local:MetroTabControl}}">
<Style.Resources>
<SolidColorBrush x:Key="TabPanelBorderBrush" Color="{Binding SelectedItem.Foreground, RelativeSource={RelativeSource AncestorType={x:Type TabControl}}}"/>
</Style.Resources>
</Style>
When I change the Color
to anything else (green, blue etc...) it works.
Whats the problem with my binding? why it doesn't work in the BasedOn
style but it does in the original?
It's funny how you say that you didn't have an errors in the Output Window in Visual Studio because when I added your code to a new project and ran it, I got the following error:
System.Windows.Data Error: 4 : Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='System.Windows.Controls.TabControl', AncestorLevel='1''. BindingExpression:Path=SelectedItem.Foreground; DataItem=null; target element is 'SolidColorBrush' (HashCode=16700594); target property is 'Color' (type 'Color')
Of course I swapped your local:MetroTabControl
for a plain old TabControl
, but the error would have been the same. You're getting this error because you have a TabControl
that is looking for a property on another TabControl
that is an ancestor of this one .
Had you tried to use the TemplatedParent RelativeSource Binding
that you used on the Rectangle
in the ControlTemplate
you would have go the following error:
System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=SelectedItem.Foreground; DataItem=null; target element is 'SolidColorBrush' (HashCode=56437836); target property is 'Color' (type 'Color')
This error is more helpful because it basically tells you that you can't access an element from a ControlTemplate
from outside that template, or more accurately as Rohit mentioned in his comment, you can't access an element that is not in the connected visual tree.
So, to answer your question, your TemplatedParent Binding
worked in the main Style
not because it was simply in the main Style
, but because it was in the ControlTemplate
in the Style
. Therefore your BasedOn
Style
didn't work because it was not in the ControlTemplate
. If you had defined the ControlTemplate
again in your BasedOn
Style
then it would have worked, but clearly you wouldn't want to do that.
A better idea to fulfil your requirement would be to Bind
the TabControl.SelectedIndex
property to an int
property in your view model and then Binding
to that same int
property and use a simple IntegerToColorConverter
for your Rectangle.Fill
property.
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.