2010-11-20 17 views
2

Ich habe die Standard GroupBox Vorlage bearbeitet, wie ich es anpassen wollte. Abgesehen von anderen Anpassungen wollte ich, dass der GroupBox-Header im Zentrum statt links oder rechts ausgerichtet wird. Die Ausrichtung des Headers ist kein Problem, das eigentliche Problem ist jedoch die OpacityMask, die für die Border-Steuerelemente definiert ist. Die Opazitätsmaske legt den transparenten Bereich hinter dem Gruppenkopf fest, in dem die Rahmen nicht gezeichnet werden. Ich bin nicht in der Lage, herauszufinden, wie ich den transparenten Platz/Abstand hinter dem Gruppenkopf platzieren kann, wenn ich den Header auf die Mitte setze.WPF GroupBox Header Anpassung

Hier ist, wie meine XAML wie folgt aussehen: (Bitte navigieren Sie zu dem Abschnitt mit „Border.OpacityMask“ ab, die die transparenten Lücke in dem Rahmen um die Kopfsätze)

<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> 

Vielen Dank für Ihre Hilfe im Voraus.

-Wajahat

+0

ich auf eine ähnliche Frage hier gekommen sind (http://stackoverflow.com/questions/2104013/wpf-groupbox- Header-Position-Alignment) wo die vorgeschlagene Antwort ist nicht was ich will. Die vorgeschlagene Lösung hier war so einfach Flip die Grenzen, so dass das Leerzeichen in der Grenze nach rechts bewegt wird. Ich möchte, dass der Header in der Mitte und nicht auf der rechten Seite steht. Vielen Dank. –

Antwort

6

ich vor etwas ähnliches einige Zeit zu tun hatte, wollte ich ein GroupBox mit zwei Header erstellen (eine auf der linken und auf der rechten Seite). Ich habe Reflector verwendet, um den Code für BorderGapMaskConverter zu erhalten, und habe ihn modifiziert, um meinen eigenen Konverter zu erstellen. Das könntest du wahrscheinlich auch hier tun.


EDIT: Ich habe meinen Konverter geändert, damit es für einen zentrierten Header funktioniert.

Hier ist die 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> 

Und hier ist der Konverter:

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

Vielen Dank Thomas, Ihr Vorschlag funktioniert wie ein Zauber. Ich bin jedoch enttäuscht von WPF, dass es immer noch eine steile Lernkurve gibt, wenn man diese Art von Anpassungen durchführt, die nicht einfach und immer noch mühsam sind. –

+0

Ja, WPF ist ein bisschen schwierig, wenn Sie anfangen ... Aber wenn Sie anfangen, es besser zu verstehen, können Sie Dinge tun, die Sie in WinForms nie hätten tun können. Wie auch immer, es ist normalerweise viel einfacher zu erreichen, was Sie wollen als in diesem speziellen Fall. Du musst diese Art von Konverter nur selten erstellen ... –

+0

+1, machte gerade die gleiche Sache und als ich den 'BorderGapMaskConverter' erreichte, dachte ich autsch ... :) Tolle Arbeit! –

Verwandte Themen