I have TabPanel
inside ScrollViewer
.
<ScrollViewer x:Name="ScrollViewer" VerticalScrollBarVisibility="Disabled" HorizontalScrollBarVisibility="Hidden">
<TabPanel x:Name="HeaderPanel" IsItemsHost="True" Panel.ZIndex="1" KeyboardNavigation.TabIndex="1" Background="Red"/>
</ScrollViewer>
I want to trigger function everytime the mouse enter/leave the ScrollViewer.
If I use it like that:
ScrollViewer sv = GetTemplateChild("ScrollViewer") as ScrollViewer;
sv.MouseEnter += sv_MouseEnter;
the function is being tirggered even if I enter the TabItem's
content area.
How can I solve it?
EDIT:
I will explain about the image below.
I want to trigger MouseEnter
when ever the user enter the area defined by the red border (which is the ScrollViewer
).
But in reality, when I use the code above, when ever I enter the TabControl
, it tirggers the MouseEnter
.
EDIT 2:
based on Sheridan's answer, here's my xaml.
my MainWindow.xaml:
<Window x:Class="WpfApplication26.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<TabControl Style="{DynamicResource TabControlStyle1}" >
<TabItem Header="TabItem">
<Grid Background="#FFE5E5E5"/>
</TabItem>
<TabItem Header="TabItem">
<Grid Background="#FFE5E5E5"/>
</TabItem>
<TabItem Header="TabItem">
<Grid Background="#FFE5E5E5"/>
</TabItem>
<TabItem Header="TabItem">
<Grid Background="#FFE5E5E5"/>
</TabItem>
<TabItem Header="TabItem">
<Grid Background="#FFE5E5E5"/>
</TabItem>
<TabItem Header="TabItem">
<Grid Background="#FFE5E5E5"/>
</TabItem>
<TabItem Header="TabItem">
<Grid Background="#FFE5E5E5"/>
</TabItem>
<TabItem Header="TabItem">
<Grid Background="#FFE5E5E5"/>
</TabItem>
<TabItem Header="TabItem">
<Grid Background="#FFE5E5E5"/>
</TabItem>
<TabItem Header="TabItem">
<Grid Background="#FFE5E5E5"/>
</TabItem>
<TabItem Header="TabItem">
<Grid Background="#FFE5E5E5"/>
</TabItem>
<TabItem Header="TabItem">
<Grid Background="#FFE5E5E5"/>
</TabItem>
</TabControl>
</Grid>
</Window>
my App.xaml:
<Application x:Class="WpfApplication26.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="MainWindow.xaml">
<Application.Resources>
<SolidColorBrush x:Key="TabControlNormalBorderBrush" Color="#8C8E94"/>
<Style x:Key="TabControlStyle1" TargetType="{x:Type TabControl}">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="Padding" Value="4,4,4,4"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="BorderBrush" Value="{StaticResource TabControlNormalBorderBrush}"/>
<Setter Property="Background" Value="#F9F9F9"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabControl}">
<Grid ClipToBounds="true" SnapsToDevicePixels="true" KeyboardNavigation.TabNavigation="Local">
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="ColumnDefinition0"/>
<ColumnDefinition x:Name="ColumnDefinition1" Width="0"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition x:Name="RowDefinition0" Height="Auto"/>
<RowDefinition x:Name="RowDefinition1" Height="*"/>
</Grid.RowDefinitions>
<ScrollViewer>
<TabPanel x:Name="HeaderPanel" Grid.Column="0" IsItemsHost="true" Margin="2,2,2,0" Grid.Row="0" KeyboardNavigation.TabIndex="1" Panel.ZIndex="1"/>
<ScrollViewer.Style>
<Style>
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Hidden" />
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Disabled" />
<Style.Triggers>
<Trigger Property="UIElement.IsMouseOver" Value="True">
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Visible" />
</Trigger>
</Style.Triggers>
</Style>
</ScrollViewer.Style>
</ScrollViewer>
<Border x:Name="ContentPanel" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Grid.Column="0" KeyboardNavigation.DirectionalNavigation="Contained" Grid.Row="1" KeyboardNavigation.TabIndex="2" KeyboardNavigation.TabNavigation="Local">
<ContentPresenter x:Name="PART_SelectedContentHost" ContentSource="SelectedContent" Margin="{TemplateBinding Padding}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="TabStripPlacement" Value="Bottom">
<Setter Property="Grid.Row" TargetName="HeaderPanel" Value="1"/>
<Setter Property="Grid.Row" TargetName="ContentPanel" Value="0"/>
<Setter Property="Height" TargetName="RowDefinition0" Value="*"/>
<Setter Property="Height" TargetName="RowDefinition1" Value="Auto"/>
<Setter Property="Margin" TargetName="HeaderPanel" Value="2,0,2,2"/>
</Trigger>
<Trigger Property="TabStripPlacement" Value="Left">
<Setter Property="Grid.Row" TargetName="HeaderPanel" Value="0"/>
<Setter Property="Grid.Row" TargetName="ContentPanel" Value="0"/>
<Setter Property="Grid.Column" TargetName="HeaderPanel" Value="0"/>
<Setter Property="Grid.Column" TargetName="ContentPanel" Value="1"/>
<Setter Property="Width" TargetName="ColumnDefinition0" Value="Auto"/>
<Setter Property="Width" TargetName="ColumnDefinition1" Value="*"/>
<Setter Property="Height" TargetName="RowDefinition0" Value="*"/>
<Setter Property="Height" TargetName="RowDefinition1" Value="0"/>
<Setter Property="Margin" TargetName="HeaderPanel" Value="2,2,0,2"/>
</Trigger>
<Trigger Property="TabStripPlacement" Value="Right">
<Setter Property="Grid.Row" TargetName="HeaderPanel" Value="0"/>
<Setter Property="Grid.Row" TargetName="ContentPanel" Value="0"/>
<Setter Property="Grid.Column" TargetName="HeaderPanel" Value="1"/>
<Setter Property="Grid.Column" TargetName="ContentPanel" Value="0"/>
<Setter Property="Width" TargetName="ColumnDefinition0" Value="*"/>
<Setter Property="Width" TargetName="ColumnDefinition1" Value="Auto"/>
<Setter Property="Height" TargetName="RowDefinition0" Value="*"/>
<Setter Property="Height" TargetName="RowDefinition1" Value="0"/>
<Setter Property="Margin" TargetName="HeaderPanel" Value="0,2,2,2"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Application.Resources>
</Application>
not working as It should (explained in the first edit) even though he says it does...
Ok... this is why you should always show us what your overall goal is. Had I not asked that, then you might not have got an answer because you were initially looking in the wrong place. Right, lecture over, on to the answer.
As it is, it's nice and simple... we don't need to handle any events, we can just use a Trigger
in the ScrollViewer.Style
. Just add this to your ScrollViewer
(making sure that you remove your ScrollBar
properties from the ScrollViewer
definition):
<ScrollViewer x:Name="ScrollViewer">
...
<ScrollViewer.Style>
<Style>
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility"
Value="Disabled" />
<Setter Property="ScrollViewer.VerticalScrollBarVisibility"
Value="Disabled" />
<Style.Triggers>
<Trigger Property="UIElement.IsMouseOver" Value="True">
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility"
Value="Visible" />
<Setter Property="ScrollViewer.VerticalScrollBarVisibility"
Value="Visible" />
</Trigger>
</Style.Triggers>
</Style>
</ScrollViewer.Style>
</ScrollViewer>
UPDATE >>>
Ok, I finally fully understand your question now... sorry for being so slow. However, you have a real problem here because this is not an error, it is the designed behaviour. This is because the TabItem
controls are inside the ScrollViewer
control, so moving the mouse over them is the same as moving them over the ScrollViewer
.
If I were trying to implement your requirements, I would abandon the TabControl
altogether and just use RadioButton
controls that load views into the lower area instead. You could even style your RadioButton
s to look like tabs if you wanted.
UPDATE 2 >>>
Well that's a long story with several parts. I don't have time to type the whole thing out here, but I'll talk you through it briefly. First you'll have to create a new ControlTemplate
for the RadioButton
s and you can put them in a StackPanel
with its Orientation
property set to True
, then put that in your ScrollViewer
.
Next, you'll need to define an enum
with one value for each 'tab' or view and an EnumToBoolConverter
... I found a good example for you in the How to bind RadioButtons to an enum? post.
The next job is to create the 'tab item content' area. For this you'll need a ContentControl
to display each view, or tab item content. The idea is that you have an abstract BaseViewModel
class that implements the INotifyPropertyChanged
interface and a class that extends this base class for each tab that you want to display. Each class will provide all of the data properties and functionality that the related view, or tab requires.
Because they all extend the base class, you can have a property of that type that you can set to each of the extended view models. This is where the ContentControl
comes into play, as it binds to the BaseViewModel
property.
The final part is to define a DataTemplate
for each view model class that simply displays the related view. Then when the various RadioButton
s are selected, you can just set the BaseViewModel
property to the relevant view model which will result in the paired view being displayed. You can see a fuller explanation with code examples in my answer to the WPF MVVM navigate views post.