Problem with the mouse click on toggleButton in WP

2019-06-24 04:59发布

I made a custom control template that turns a groupbox into an expander (clicking on the header expands/collapses the content of the groupbox). It works fine except that mouse clicks don't always go through: sometimes it doesn't expand/collapse when you click on the header, esp. when you click inside the "o"s in the word "Colors". I organically thought it was caused by the text in the header trapping mouse clicks which prevent them from going through so I played around with the IsHitTestVisible and IsFocusable properties on the content header, etc., which doesn't seem to have any effect. A header that only contains empty strings or even no content seems to have the same issue.

The XAML is posted below.

(BTW, this post which turns an expander into a groupbox seems to have similar issue: If you click right inside the arrow, the togglebutton won't toggle.)

<Window x:Class="TestCollapsibleGroupBoxStyle.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">
<Window.Resources>

    <BooleanToVisibilityConverter x:Key="boolToVizConverter"/>

    <Color x:Key="HyperlinkHoverBlue">#FF0088CC</Color>
    <SolidColorBrush x:Key="HyperlinkHoverBlueBrush" Color="{StaticResource HyperlinkHoverBlue}" />
    <PathGeometry x:Key="TreeArrow">
        <PathGeometry.Figures>
            <PathFigureCollection>
                <PathFigure IsFilled="True"
                                    StartPoint="0 0"
                                    IsClosed="True">
                    <PathFigure.Segments>
                        <PathSegmentCollection>
                            <LineSegment Point="0 6"/>
                            <LineSegment Point="6 0"/>
                        </PathSegmentCollection>
                    </PathFigure.Segments>
                </PathFigure>
            </PathFigureCollection>
        </PathGeometry.Figures>
    </PathGeometry>
    <BorderGapMaskConverter x:Key="BorderGapMaskConverter"/>

    <Style x:Key="CollapsibleGroupBoxStyle" TargetType="{x:Type GroupBox}" BasedOn="{StaticResource {x:Type GroupBox}}">
        <Style.Resources>

            <Style x:Key="ToggleHeaderStyle" TargetType="ToggleButton" BasedOn="{StaticResource {x:Type ToggleButton}}">
                <Setter Property="MinWidth" Value="72"/>
                <Setter Property="Padding" Value="2,1"/>
                <Setter Property="SnapsToDevicePixels" Value="True"/>
                <Setter Property="FontSize" Value="18"/>
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="ToggleButton">
                            <Border Background="Transparent" MinHeight="30"
                                Padding="{TemplateBinding Padding}" Focusable="False">
                                <Grid Background="Transparent" SnapsToDevicePixels="False">
                                    <ContentPresenter Margin="{TemplateBinding Padding}"
                                                VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                                                HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                                Focusable="False"
                                                SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                                    <Path x:Name="ExpandPath"
                                            VerticalAlignment="Center"
                                            Margin="4,2,0,0"
                                          HorizontalAlignment="Right"
                                            Fill="Transparent"
                                            Stroke="#FF989898"
                                            Data="{StaticResource TreeArrow}">
                                        <Path.RenderTransform>
                                            <RotateTransform Angle="135"
                                                         CenterX="3"
                                                         CenterY="3"/>
                                        </Path.RenderTransform>
                                    </Path>

                                </Grid>
                            </Border>
                            <ControlTemplate.Triggers>
                                <Trigger Property="IsMouseOver" Value="True">
                                    <Trigger.Setters>
                                        <Setter Property="Foreground" Value="{StaticResource HyperlinkHoverBlueBrush}"/>
                                        <Setter TargetName="ExpandPath" Property="Stroke" Value="#FF1BBBFA"/>
                                        <Setter TargetName="ExpandPath" Property="Fill" Value="Transparent"/>
                                    </Trigger.Setters>
                                </Trigger>
                                <Trigger Property="IsChecked" Value="True">
                                    <Setter TargetName="ExpandPath" Property="RenderTransform">
                                        <Setter.Value>
                                            <RotateTransform Angle="180"
                                                                 CenterX="3"
                                                                 CenterY="3"/>
                                        </Setter.Value>
                                    </Setter>
                                    <Setter TargetName="ExpandPath" Property="Fill" Value="#FF595959"/>
                                    <Setter TargetName="ExpandPath" Property="Stroke" Value="#FF262626"/>
                                </Trigger>
                            </ControlTemplate.Triggers>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </Style.Resources>
        <Setter Property="Background" Value="Transparent"/>
        <Setter Property="BorderBrush"
                    Value="Gray"/>
        <Setter Property="BorderThickness"
                    Value="1"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type GroupBox}">
                    <Grid SnapsToDevicePixels="true">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="6"/>
                            <ColumnDefinition Width="Auto"/>
                            <ColumnDefinition Width="*"/>
                            <ColumnDefinition Width="6"/>
                        </Grid.ColumnDefinitions>
                        <Grid.RowDefinitions>
                            <RowDefinition Height="Auto"/>
                            <RowDefinition Height="Auto"/>
                            <RowDefinition Height="*"/>
                            <RowDefinition Height="6"/>
                        </Grid.RowDefinitions>
                        <Border CornerRadius="4"
                                    Grid.Row="1"
                                    Grid.RowSpan="3"
                                    Grid.Column="0"
                                    Grid.ColumnSpan="4"
                                    BorderThickness="{TemplateBinding BorderThickness}"
                                    BorderBrush="Transparent"
                                    Background="{TemplateBinding Background}"/>
                        <Border x:Name="Header"
                                    Padding="3,1,3,0"
                                    Grid.Row="0"
                                    Grid.RowSpan="2"
                                    Grid.Column="1">
                            <ToggleButton x:Name="headerToggleBtn" 
                                    Content="{TemplateBinding Header}"
                                    Style="{StaticResource ToggleHeaderStyle}">
                            </ToggleButton>
                        </Border>
                        <ContentPresenter x:Name="ContentSite" Grid.Row="2"
                                        Grid.Column="1"
                                        Grid.ColumnSpan="2"
                                        Margin="{TemplateBinding Padding}"
                                        SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                        <Border CornerRadius="4"
                                    Grid.Row="1"
                                    Grid.RowSpan="3"
                                    Grid.ColumnSpan="4"
                                    BorderThickness="{TemplateBinding BorderThickness}"
                                    BorderBrush="White">
                            <Border.OpacityMask>
                                <MultiBinding Converter="{StaticResource BorderGapMaskConverter}"
                                                        ConverterParameter="7">
                                    <Binding ElementName="Header"
                                                 Path="ActualWidth"/>
                                    <Binding RelativeSource="{RelativeSource Self}"
                                                 Path="ActualWidth"/>
                                    <Binding RelativeSource="{RelativeSource Self}"
                                                 Path="ActualHeight"/>
                                </MultiBinding>
                            </Border.OpacityMask>

                            <Border BorderThickness="{TemplateBinding BorderThickness}"
                                        BorderBrush="{TemplateBinding BorderBrush}"
                                        CornerRadius="3">
                                <Border BorderThickness="{TemplateBinding BorderThickness}"
                                            BorderBrush="White"
                                            CornerRadius="2"/>
                            </Border>
                        </Border>
                    </Grid>
                    <ControlTemplate.Triggers>
                        <DataTrigger Binding="{Binding ElementName=headerToggleBtn, Path=IsChecked}" Value="False">
                            <Setter Property="Visibility" TargetName="ContentSite" Value="Collapsed"/>
                        </DataTrigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>

    </Style>

</Window.Resources>
<StackPanel Orientation="Horizontal">
    <GroupBox Header="Colors" Style="{StaticResource CollapsibleGroupBoxStyle}">
        <StackPanel Orientation="Vertical">
            <RadioButton GroupName="colorGrp" Content="Red"/>
            <RadioButton GroupName="colorGrp" Content="Blue"/>
            <RadioButton GroupName="colorGrp" Content="Red"/>
        </StackPanel>
    </GroupBox>

    <GroupBox>
        <GroupBox.Header>
            <ToggleButton Name="ToggleHeader">
                <TextBlock Text="Colors" FontSize="18"/>
            </ToggleButton>
        </GroupBox.Header>
        <StackPanel Orientation="Vertical" Visibility="{Binding ElementName=ToggleHeader, Path=IsChecked, Mode=TwoWay, Converter={StaticResource boolToVizConverter}}">
            <RadioButton GroupName="colorGrp" Content="Red"/>
            <RadioButton GroupName="colorGrp" Content="Blue"/>
            <RadioButton GroupName="colorGrp" Content="Red"/>
        </StackPanel>
    </GroupBox>

    <GroupBox Header="      " Style="{StaticResource CollapsibleGroupBoxStyle}">
        <StackPanel Orientation="Vertical">
            <RadioButton GroupName="colorGrp" Content="Red"/>
            <RadioButton GroupName="colorGrp" Content="Blue"/>
            <RadioButton GroupName="colorGrp" Content="Red"/>
        </StackPanel>
    </GroupBox>
</StackPanel>
</Window>

1条回答
地球回转人心会变
2楼-- · 2019-06-24 05:44

Set IsHitTestVisible of your groupbox's border to False:

<Border
    Grid.ColumnSpan="4"
    Grid.Row="1"
    Grid.RowSpan="3"
    BorderBrush="White"
    BorderThickness="{TemplateBinding BorderThickness}"
    CornerRadius="4" 
    IsHitTestVisible="False">   
    <Border.OpacityMask>
    <MultiBinding Converter="{StaticResource BorderGapMaskConverter}" ConverterParameter="7">
        <Binding ElementName="Header" Path="ActualWidth"/>
        <Binding Path="ActualWidth" RelativeSource="{RelativeSource Self}"/>
        <Binding Path="ActualHeight" RelativeSource="{RelativeSource Self}"/>
    </MultiBinding>
    </Border.OpacityMask>
    <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="3">
    <Border BorderBrush="White" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="2"/>
</Border>
查看更多
登录 后发表回答