Wpf 在仅设置了上边框厚度的边框上使用不透明度遮罩

Wpf 在仅设置了上边框厚度的边框上使用不透明度遮罩,wpf,expander,opacitymask,Wpf,Expander,Opacitymask,您好,我一直在尝试覆盖WPF中的Expander控件,以使用位于标题“下方”的分隔线 我找到了一个示例,说明了如何使扩展器看起来像一个分组框,但我不希望边框一直显示,只显示在边框的顶部 我面临的问题是,边框使用不透明度遮罩处理标题下的边框,但当我将边框厚度设置为0,1,0,0时,不透明度遮罩似乎失败。将任何其他边界设置为1+似乎可以使其再次工作(1,1,0,0),但我不明白为什么这会产生任何影响,以及是否有任何其他方法可以实现所需的结果 我现有的XAML如下 <Contro

您好,我一直在尝试覆盖WPF中的
Expander
控件,以使用位于标题“下方”的分隔线

我找到了一个示例,说明了如何使
扩展器
看起来像一个分组框,但我不希望边框一直显示,只显示在边框的顶部

我面临的问题是,边框使用不透明度遮罩处理标题下的边框,但当我将边框厚度设置为0,1,0,0时,不透明度遮罩似乎失败。将任何其他边界设置为1+似乎可以使其再次工作(1,1,0,0),但我不明白为什么这会产生任何影响,以及是否有任何其他方法可以实现所需的结果

我现有的XAML如下

        <ControlTemplate TargetType="{x:Type Expander}">
            <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" Grid.Column="1" Grid.Row="0" Grid.RowSpan="2" Padding="3,0,3,0">
                    <Grid SnapsToDevicePixels="False" Background="Transparent" Grid.Column="1" Grid.Row="0" Grid.RowSpan="2">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition />
                            <ColumnDefinition />
                        </Grid.ColumnDefinitions>
                        <ToggleButton Grid.Column="0" MinHeight="0" MinWidth="0"
                            Name="HeaderToggle"
                            IsChecked="{Binding Path=IsExpanded, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}" >
                            <ToggleButton.Template>
                                <ControlTemplate TargetType="{x:Type ToggleButton}">
                                    <Grid SnapsToDevicePixels="False" Background="Transparent">
                                        <Ellipse HorizontalAlignment="Center" x:Name="circle" VerticalAlignment="Center" Width="15" Height="15" Fill="{DynamicResource ButtonNormalBackgroundFill}" Stroke="DarkGray"/>
                                        <Ellipse Visibility="Hidden" HorizontalAlignment="Center" x:Name="shadow" VerticalAlignment="Center" Width="13" Height="13" Fill="{DynamicResource ExpanderShadowFill}"/>
                                        <Path SnapsToDevicePixels="false" x:Name="arrow" VerticalAlignment="Center" HorizontalAlignment="Center" Stroke="#666" StrokeThickness="2" Data="M1,1 L4,4 7,1" />
                                    </Grid>

                                    <ControlTemplate.Triggers>
                                        <Trigger Property="IsChecked" Value="true">
                                            <Setter Property="Data" TargetName="arrow" Value="M 1,4  L 4,1  L 7,4"/>
                                        </Trigger>
                                        <Trigger Property="IsMouseOver" Value="true">
                                            <Setter Property="Stroke" TargetName="circle" Value="#666"/>
                                            <Setter Property="Stroke" TargetName="arrow" Value="#222"/>
                                            <Setter Property="Visibility" TargetName="shadow" Value="Visible"/>
                                        </Trigger>
                                    </ControlTemplate.Triggers>
                                </ControlTemplate>
                            </ToggleButton.Template>
                        </ToggleButton>
                        <ContentPresenter ContentSource="Header" RecognizesAccessKey="true"
                            TextElement.Foreground="{StaticResource GroupBoxHeaderBrush}"
                            SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" Grid.Column="1" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="3,0,0,0" />
                    </Grid>
                </Border>

                <ContentPresenter x:Name="ExpandSite" Visibility="Collapsed" Grid.Row="2" Grid.Column="1" Grid.ColumnSpan="2" Margin="{TemplateBinding Padding}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />


                <Border Grid.Row="1" Grid.ColumnSpan="4" BorderThickness="0,1,0,0" BorderBrush="{TemplateBinding BorderBrush}" >
                    <Border.OpacityMask>
                        <MultiBinding Converter="{StaticResource BorderGapMaskConverter}" ConverterParameter="7">
                            <Binding Path="ActualWidth" ElementName="Header"/>
                            <Binding Path="ActualWidth" RelativeSource="{RelativeSource Self}"/>
                            <Binding Path="ActualHeight" RelativeSource="{RelativeSource Self}"/>
                        </MultiBinding>
                    </Border.OpacityMask>
                </Border>

            </Grid>
            <ControlTemplate.Triggers>
                <Trigger Property="IsExpanded" Value="true">
                    <Setter Property="Visibility" TargetName="ExpandSite" Value="Visible"/>
                </Trigger>
                <Trigger Property="IsEnabled" Value="false">
                    <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
                </Trigger>

            </ControlTemplate.Triggers>
        </ControlTemplate>

编辑:下面我实际上是指后面

好的,我已经拍了一张我想在视觉上看到的照片,现在在最右的角落里增加了一个按钮的复杂性

我很高兴创建一个复杂的面具来处理额外的控制,但我只是不知道如何,我相信我实际上不需要一个边界,因为只有一条线就可以了

任何帮助都将不胜感激,请记住我希望切换按钮的背景和标题文本是透明的,以便复制父控件的背景


谢谢更新:

好的,我可以把你的截图翻译成

Xaml:


我还删除了一些未被使用的
网格
,并删除了一些
网格
附加属性,这些属性甚至不是
网格
的子项

主要的变化是删除
边框
OpacityMask
,只在相应的
网格
列中渲染高度为1的
矩形。通过这种方式,实际上根本不渲染标题后面的任何内容


当您将
按钮添加到右侧时,可以扩展此概念。只需将它放在自己的网格列中,不要在该列中呈现一个
矩形

更新:

好的,我可以把你的截图翻译成

Xaml:


我还删除了一些未被使用的
网格
,并删除了一些
网格
附加属性,这些属性甚至不是
网格
的子项

主要的变化是删除
边框
OpacityMask
,只在相应的
网格
列中渲染高度为1的
矩形。通过这种方式,实际上根本不渲染标题后面的任何内容


当您将
按钮添加到右侧时,可以扩展此概念。只需将它放在自己的网格列中,不要在该列中渲染一个
矩形

对不起,是的,我的意思是后面的,但是上面的选项不够好,因为如果我将它作为一个普通控件,我可能希望该控件在某些位置是透明的,并且没有自己的背景,因此
<ControlTemplate TargetType="{x:Type Expander}">
  <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="*" />
    </Grid.RowDefinitions>
    <Rectangle Grid.Row="0"
                Grid.Column="0"
                Height="1"
                Margin="0 4 0 0"
                VerticalAlignment="Center"
                Fill="{TemplateBinding BorderBrush}" />
    <Rectangle Grid.Row="0"
                Grid.Column="2"
                Grid.ColumnSpan="2"
                Height="1"
                Margin="0 4 0 0"
                VerticalAlignment="Center"
                Fill="{TemplateBinding BorderBrush}" />
    <Border x:Name="Header"
            Grid.Row="0"
            Grid.Column="1"
            Padding="3,0,3,0">
      <Grid Background="Transparent"
            SnapsToDevicePixels="False">
        <Grid.ColumnDefinitions>
          <ColumnDefinition />
          <ColumnDefinition />
        </Grid.ColumnDefinitions>
        <ToggleButton Name="HeaderToggle"
                      Grid.Column="0"
                      MinWidth="0"
                      MinHeight="0"
                      IsChecked="{Binding Path=IsExpanded,
                                          Mode=TwoWay,
                                          RelativeSource={RelativeSource TemplatedParent}}">
          <ToggleButton.Template>
            <ControlTemplate TargetType="{x:Type ToggleButton}">
              <Grid Background="Transparent"
                    SnapsToDevicePixels="False">
                <Ellipse x:Name="circle"
                          Width="15"
                          Height="15"
                          HorizontalAlignment="Center"
                          VerticalAlignment="Center"
                          Fill="{DynamicResource ButtonNormalBackgroundFill}"
                          Stroke="DarkGray" />
                <Ellipse x:Name="shadow"
                          Width="13"
                          Height="13"
                          HorizontalAlignment="Center"
                          VerticalAlignment="Center"
                          Fill="{DynamicResource ExpanderShadowFill}"
                          Visibility="Hidden" />
                <Path x:Name="arrow"
                      HorizontalAlignment="Center"
                      VerticalAlignment="Center"
                      Data="M1,1 L4,4 7,1"
                      SnapsToDevicePixels="false"
                      Stroke="#666"
                      StrokeThickness="2" />
              </Grid>
              <ControlTemplate.Triggers>
                <Trigger Property="IsChecked"
                          Value="true">
                  <Setter TargetName="arrow"
                          Property="Data"
                          Value="M 1,4  L 4,1  L 7,4" />
                </Trigger>
                <Trigger Property="IsMouseOver"
                          Value="true">
                  <Setter TargetName="circle"
                          Property="Stroke"
                          Value="#666" />
                  <Setter TargetName="arrow"
                          Property="Stroke"
                          Value="#222" />
                  <Setter TargetName="shadow"
                          Property="Visibility"
                          Value="Visible" />
                </Trigger>
              </ControlTemplate.Triggers>
            </ControlTemplate>
          </ToggleButton.Template>
        </ToggleButton>
        <ContentPresenter Grid.Column="1"
                          Margin="3,0,0,0"
                          HorizontalAlignment="Left"
                          VerticalAlignment="Center"
                          ContentSource="Header"
                          RecognizesAccessKey="true"
                          SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
                          TextElement.Foreground="Black" />
      </Grid>
    </Border>
    <ContentPresenter x:Name="ExpandSite"
                      Grid.Row="1"
                      Grid.Column="1"
                      Grid.ColumnSpan="2"
                      Margin="{TemplateBinding Padding}"
                      SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
                      Visibility="Collapsed" />
  </Grid>
  <ControlTemplate.Triggers>
    <Trigger Property="IsExpanded"
              Value="true">
      <Setter TargetName="ExpandSite"
              Property="Visibility"
              Value="Visible" />
    </Trigger>
    <Trigger Property="IsEnabled"
              Value="false">
      <Setter Property="Foreground"
              Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}" />
    </Trigger>
  </ControlTemplate.Triggers>
</ControlTemplate>