2010-11-20 92 views
2

カスタマイズしたい標準のGroupBoxテンプレートを編集しました。他のカスタマイズとは別に、GroupBoxのヘッダーをHorizo​​ntally LeftまたはRightの代わりにCenterで整列させたいと思っていました。ヘッダーの配置は問題ではありませんが、本当の問題は境界線コントロール用に定義されたOpacityMaskです。不透明度マスクは、枠線が描画されていないグループボックスヘッダの後ろの透明な領域を設定します。ヘッダーを中央に設定すると、グループボックスヘッダーの後ろに透明なスペース/ギャップを配置する方法を理解できませんでした。ここでWPF GroupBoxヘッダーのカスタマイズ

は私のXAMLは、どのように見えるかです:

<ControlTemplate x:Key="GroupBoxControlTemplate1" 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 Background="{TemplateBinding Background}" BorderBrush="Transparent" 
    BorderThickness="{TemplateBinding BorderThickness}" 
    CornerRadius="4" Grid.Column="1 " Grid.ColumnSpan="4" 
    Grid.Row="1" Grid.RowSpan="3" HorizontalAlignment="Stretch"/> 

    <Border x:Name="Header" Grid.Column="2" Grid.RowSpan="2" HorizontalAlignment="Left" 
     Padding="3,1,3,0" VerticalAlignment="Stretch"> 
     <Border.Effect> 
      <DropShadowEffect BlurRadius="10" Direction="334"/> 
     </Border.Effect> 
     <ContentPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" 
     Content="{TemplateBinding Header}" 
     ContentSource="Header" 
     ContentStringFormat="{TemplateBinding HeaderStringFormat}" 
     ContentTemplate="{TemplateBinding HeaderTemplate}" 
     RecognizesAccessKey="True" Height="Auto" 
     VerticalAlignment="Center" 
     HorizontalAlignment="Center" 
     OpacityMask="#FF3844BD" Margin="0,1,0,0"> 
     </ContentPresenter> 
    </Border> 

    <ContentPresenter Margin="{TemplateBinding Padding}" 
     SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" 
     Content="{TemplateBinding Content}" 
     ContentStringFormat="{TemplateBinding ContentStringFormat}" 
     ContentTemplate="{TemplateBinding ContentTemplate}" 
     Grid.Column="1" Grid.ColumnSpan="2" Grid.Row="2"/> 
    <Border BorderBrush="White" BorderThickness="{TemplateBinding BorderThickness}" 
     CornerRadius="4" Grid.ColumnSpan="3" Grid.Row="1" Grid.RowSpan="3" RenderTransformOrigin="0.5,0.5" Margin="0"> 
     <Border.OpacityMask> 
      <MultiBinding ConverterParameter="7" UpdateSourceTrigger="Default"> 
       <MultiBinding.Converter> 
        <BorderGapMaskConverter/> 
       </MultiBinding.Converter> 
       <Binding Path="ActualWidth" ElementName="Header"/> 
       <Binding Path="ActualWidth" RelativeSource="{RelativeSource Self}"/> 
       <Binding Path="ActualHeight" RelativeSource="{RelativeSource Self}"/> 
      </MultiBinding> 
     </Border.OpacityMask> 
     <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="4"> 
      <Border BorderBrush="White" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="4"/> 
     </Border> 
    </Border> 
</Grid> 

多くのおかげで(ヘッダーの周囲に境界線に透明ギャップを設定し、「Border.OpacityMask」で始まるセクションに移動してください)事前にあなたの助けを借りてください。私はいくつかの時間前に似た何かをしなければならなかった

+0

(http://stackoverflow.com/questions/2104013/wpf-groupbox- header-postion-alignment)ここで提案された答えは私が望むものではありません。ここで提案されている解決策は、境界線の余白が右に移動するように境界線を単純に反転させることでした。ヘッダーを中央に、右にはしたくない。ありがとう。 –

答えて

6

-Wajahat

は、私は2つのヘッダ(左1、右に1つずつ)でのGroupBoxを作りたかったのです。私はReflectorを使ってBorderGapMaskConverterのコードを取得し、独自のコンバータを作成するように修正しました。あなたはおそらく同じことをここで行うことができます。


EDIT:私はそれが中央のヘッダーのために働くように変更しました。

はここControlTemplate

<ControlTemplate TargetType="{x:Type GroupBox}"> 
    <Grid SnapsToDevicePixels="true"> 
     <Grid.ColumnDefinitions> 
      <ColumnDefinition Width="6"/> 
      <ColumnDefinition Width="*"/> 
      <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="5" 
      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="2"> 
      <ContentPresenter ContentSource="Header" 
          RecognizesAccessKey="True" 
          SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/> 
     </Border> 
     <ContentPresenter Grid.Row="2" 
         Grid.Column="1" 
         Grid.ColumnSpan="3" 
         Margin="{TemplateBinding Padding}" 
         SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/> 
     <Border CornerRadius="4" 
      Grid.Row="1" 
      Grid.RowSpan="3" 
      Grid.ColumnSpan="5" 
      BorderThickness="{TemplateBinding BorderThickness}" 
      BorderBrush="White"> 
      <Border.OpacityMask> 
       <MultiBinding Converter="{StaticResource CenterBorderGapMaskConverter}"> 
        <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> 

だし、ここでAコンバータです:私はここに同様の問題に遭遇してきた

class CenterBorderGapMaskConverter : IMultiValueConverter 
{ 
    // Methods 
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) 
    { 
     Type type = typeof(double); 
     if (values == null 
      || values.Length != 3 
      || values[0] == null 
      || values[1] == null 
      || values[2] == null 
      || !type.IsAssignableFrom(values[0].GetType()) 
      || !type.IsAssignableFrom(values[1].GetType()) 
      || !type.IsAssignableFrom(values[2].GetType())) 
     { 
      return DependencyProperty.UnsetValue; 
     } 

     double pixels = (double)values[0]; 
     double width = (double)values[1]; 
     double height = (double)values[2]; 
     if ((width == 0.0) || (height == 0.0)) 
     { 
      return null; 
     } 
     Grid visual = new Grid(); 
     visual.Width = width; 
     visual.Height = height; 
     ColumnDefinition colDefinition1 = new ColumnDefinition(); 
     ColumnDefinition colDefinition2 = new ColumnDefinition(); 
     ColumnDefinition colDefinition3 = new ColumnDefinition(); 
     colDefinition1.Width = new GridLength(1.0, GridUnitType.Star); 
     colDefinition2.Width = new GridLength(pixels); 
     colDefinition3.Width = new GridLength(1.0, GridUnitType.Star); 
     visual.ColumnDefinitions.Add(colDefinition1); 
     visual.ColumnDefinitions.Add(colDefinition2); 
     visual.ColumnDefinitions.Add(colDefinition3); 
     RowDefinition rowDefinition1 = new RowDefinition(); 
     RowDefinition rowDefinition2 = new RowDefinition(); 
     rowDefinition1.Height = new GridLength(height/2.0); 
     rowDefinition2.Height = new GridLength(1.0, GridUnitType.Star); 
     visual.RowDefinitions.Add(rowDefinition1); 
     visual.RowDefinitions.Add(rowDefinition2); 
     Rectangle rectangle1 = new Rectangle(); 
     Rectangle rectangle2 = new Rectangle(); 
     Rectangle rectangle3 = new Rectangle(); 
     rectangle1.Fill = Brushes.Black; 
     rectangle2.Fill = Brushes.Black; 
     rectangle3.Fill = Brushes.Black; 
     Grid.SetRowSpan(rectangle1, 2); 
     Grid.SetRow(rectangle1, 0); 
     Grid.SetColumn(rectangle1, 0); 
     Grid.SetRow(rectangle2, 1); 
     Grid.SetColumn(rectangle2, 1); 
     Grid.SetRowSpan(rectangle3, 2); 
     Grid.SetRow(rectangle3, 0); 
     Grid.SetColumn(rectangle3, 2); 
     visual.Children.Add(rectangle1); 
     visual.Children.Add(rectangle2); 
     visual.Children.Add(rectangle3); 
     return new VisualBrush(visual); 
    } 

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) 
    { 
     return new object[] { Binding.DoNothing }; 
    } 
} 
+0

多くのおかげでトーマス、あなたの提案は魅力のように動作します。しかし、私はWPFには失望していますが、このようなカスタマイズを行う際にはまだまだ熟練した学習曲線が必要であり、それは簡単ではなく、面倒です。 –

+0

はい、始めるとWPFハードが少し難しいです...しかし、あなたがそれをよく理解し始めたら、あなたはWinFormsで決してできなかったことをすることができます。とにかく、この特定の場合よりも、あなたが望むものを達成することは、通常はずっと簡単です。あなたはめったにこの種類のコンバーターを作成する必要はありません... –

+0

+1は、同じことをやっていました。私が「BorderGapMaskConverter」に到達したとき、私は大好きでした... :)素晴らしい仕事! –

関連する問題