WPF禁用子项上的MouseEnter触发器

时间:2013-11-08 11:03:15

标签: wpf custom-controls scrollviewer mouseenter event-bubbling

TabPanel内有ScrollViewer

<ScrollViewer x:Name="ScrollViewer" VerticalScrollBarVisibility="Disabled" HorizontalScrollBarVisibility="Hidden">
    <TabPanel x:Name="HeaderPanel" IsItemsHost="True" Panel.ZIndex="1" KeyboardNavigation.TabIndex="1" Background="Red"/>
</ScrollViewer>

我想在每次鼠标进入/离开ScrollViewer时触发功能。

如果我这样使用它:

ScrollViewer sv = GetTemplateChild("ScrollViewer") as ScrollViewer;
sv.MouseEnter += sv_MouseEnter;

即使我输入TabItem's内容区域,该功能仍在进行中 我该如何解决?

修改
我会解释下面的图片。 当用户进入红色边框定义的区域(MouseEnter)时,我想触发ScrollViewer

但实际上,当我使用上面的代码时,当我输入TabControl时,它会转移MouseEnter

enter image description here

编辑2:
根据Sheridan的回答,这是我的xaml。

我的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>

我的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>

不能正常工作(在第一次编辑中解释)即使他说它确实......

1 个答案:

答案 0 :(得分:1)

好的......这就是为什么你应该总是告诉我们你的总体目标是什么。如果我没有问过,那么你可能没有得到答案,因为你最初看错了地方。是的,讲座,回答。

实际上,它很简单......我们不需要处理任何事件,我们可以在Trigger中使用ScrollViewer.Style。只需将其添加到ScrollViewer(确保从ScrollBar定义中删除ScrollViewer属性):

<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>

更新&gt;&gt;&gt;

好的,我现在终于明白了你的问题...对不起这么慢。但是,这里有一个真正的问题,因为这不是错误,而是设计行为。这是因为TabItem控件位于 ScrollViewer控件内,因此将鼠标移到它们上方与将它们移到ScrollViewer上相同。

如果我尝试实现您的要求,我会完全放弃TabControl,只使用RadioButton控件将视图加载到较低区域。如果需要,您甚至可以将RadioButton样式设置为标签。


更新2&gt;&gt;&gt;

这是一个有很多部分的长篇故事。我没有时间在这里输入整件事,但我会简短地介绍一下。首先,您必须为ControlTemplate创建新的RadioButton,并且可以将StackPanel的{​​{1}}属性设置为Orientation,然后将其放入True

接下来,您需要为每个“标签”或视图定义ScrollViewer一个值,并enum ...我在How to bind RadioButtons to an enum?找到了一个很好的例子} post。

接下来的工作是创建“标签项内容”区域。为此,您需要EnumToBoolConverter来显示每个视图或标签项内容。我们的想法是,您有一个实现ContentControl接口的抽象BaseViewModel类,以及一个为您要显示的每个选项卡扩展此基类的类。每个类都将提供相关视图或选项卡所需的所有数据属性和功能。

因为它们都扩展了基类,所以您可以拥有可以设置为每个扩展视图模型的该类型的属性。这是INotifyPropertyChanged发挥作用的地方,因为它绑定到ContentControl属性。

最后一部分是为每个视图模型类定义一个BaseViewModel,只显示相关视图。然后,当选择了各种DataTemplate时,您只需将RadioButton属性设置为相关的视图模型,这将导致显示配对视图。在我对WPF MVVM navigate views帖子的回答中,您可以通过代码示例看到更完整的解释。