【问题标题】:Using opacity mask on a border with only top border thickness set在仅设置顶部边框厚度的边框上使用不透明蒙版
【发布时间】:2013-05-01 13:43:55
【问题描述】:

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

我找到了一个如何让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>

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

好的,我已经拍摄了一个我想要直观地看到的示例,现在在最右角添加了一个按钮的复杂性。

我很高兴创建一个复杂的蒙版来处理额外的控件,但我不知道怎么做,而且我确定我实际上不需要边框,就像单行一样。

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

谢谢

【问题讨论】:

    标签: wpf expander opacitymask


    【解决方案1】:

    更新:

    好的,我可以把你的截图翻译成类似的东西

    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="*" />
        </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>
    

    我也确实删除了一些未被使用的GridRows,并删除了一些Grid附加属性,这些属性被设置为甚至不是Grid的子项。

    主要的变化几乎是删除BorderOpacityMask 并在适当的Grid 列中呈现高度为1 的Rectangle。这样你实际上根本不会在标题后面渲染任何东西。

    当您将Button 添加到右侧时,您可以扩展这个概念。只需将它放在它自己的网格列中,不要在该列中呈现Rectangle

    【讨论】:

    • 对不起,我的意思是落后,但是上面的选项还不够好,好像我把它作为一个通用控件我可能希望控件在某些地方是透明的并且没有自己的背景,因此仍然离开我遇到了通过标题控件出现边框的问题。谢谢
    • 你能张贴一张你期望这个样子的截图吗?我仍然很困惑。如果您将我提到的后面和下面的方法结合起来,我认为您会拥有所需的东西,但如果不是那么需要查看预期渲染的图片
    • 对不起,我很难得到我想要的截图,因为我无法实现我想要的。但是,您的第一个建议完全按照我的意愿工作,直到我使切换按钮和标题背景透明,然后边框通过这些控件变得可见。我知道我需要一个不透明蒙版,但我不明白如何正确使用它,我不明白为什么只有顶部边框厚度不起作用。谢谢
    • @Kezza 使用绘画或其他一些简单的工具,然后快速制作您需要的模型。即使破旧只是确保它描绘了您的意图,那应该就可以了。如果没有您的要求的视觉提示,我只是不确定该建议什么。
    • 啊哈,我知道你在那里做了什么。这将完成这项工作,我可能会想出一个自定义控件来重用这种扩展器样式。谢谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-24
    • 2013-10-06
    相关资源
    最近更新 更多