2013-05-01 68 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