2013-05-01 66 views
1

嗨我一直试图覆盖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> 

编辑:通过下面我实际上意味着背后

好了,所以我有照片逛过什么,我希望看到直观的例子,现在又增加了最右边角落按钮的复杂性。

example screenshot

我很高兴地创建复杂的面具,以应对额外的控制,但我不知道我怎么和敢肯定,我不真的需要一个边框,只是一个单一的线会怎么做。

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

感谢

回答

1

更新:

好吧,我可以让你的屏幕截图转换为类似

enter image description here

的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,只是渲染Rectangle的与1在适当Grid柱的高度。这样你实际上不会在头部后面渲染任何东西。

当您向右侧添加Button时,可以扩展此c的概念。只要把它在自己的网格列,不渲染该列中

+0

对不起,是我的意思后面Rectangle,但上面的选项不够好,如果我让这个共同的控制我可能要控制要透明的地方,并没有自己的背景,因此仍然留下边框通过标题控件出现的问题。谢谢 – Kezza 2013-05-01 16:07:53

+0

你可以发表一个截图,说明你期待这看起来像请。我仍然感到困惑。如果你把两个后面,下面的方法,我提到我倒是觉得你有你需要什么,但如果它不是那么需要看你的期望的PIC渲染 – Viv 2013-05-01 17:59:51

+0

对不起,我struggleing获得的截图什么我想要我无法达到我想要的。然而,你的第一个建议完全按照我的意愿工作,直到我将切换按钮和标题背景变为透明为止,然后边界通过这些控件变得可见。我知道我需要一个不透明的面具,但我不明白如何正确使用它,我不明白为什么只有顶部边框厚度不起作用。谢谢 – Kezza 2013-05-03 17:21:19