Вы можете, но это не очень!
<GroupBox>
<GroupBox.Header>
<TextBlock Text="Hello">
<TextBlock.RenderTransform>
<RotateTransform Angle="90" CenterX="0" CenterY="0" />
</TextBlock.RenderTransform>
</TextBlock>
</GroupBox.Header>
<TextBlock Text="World!"/>
</GroupBox>
Вы также будете нуждаться, чтобы изменить style of the GroupBox поддержать это.
Это похоже на его сетку с несколькими строками, пару презентаторов контента и пару границ, поэтому можно было бы превратить это в столбцы и перейти оттуда. Я бы поставил Rotate на ContentPresenter, который делает заголовок, поэтому вы можете просто применить свой стиль, где бы вы этого ни хотели.
Final Update
Извлекая шаблон из стандартного контроля мы можем изменить его, чтобы переместить заголовок раунд, однако мы также считаем, что есть конвертер используется для маскировки границы вокруг. Используя декомпилятор (DotPeek), мы также можем переключаться вокруг строк и столбцов, чтобы переместить зазор в сторону.
Так шаблон выглядит следующим образом
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<BorderGapMaskConverter x:Key="BorderGapMaskConverter"/>
<Style x:Key="GroupBoxStyle1" TargetType="{x:Type GroupBox}">
<Setter Property="BorderBrush" Value="#D5DFE5"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type GroupBox}">
<Grid SnapsToDevicePixels="true">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="6"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="6"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="6"/>
</Grid.RowDefinitions>
<Border BorderBrush="Transparent" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Grid.ColumnSpan="3" Grid.Column="1" CornerRadius="4" Grid.Row="0" Grid.RowSpan="4"/>
<Border x:Name="Header" Grid.Column="0" Padding="3,1,3,0" Grid.Row="1" Grid.ColumnSpan="2">
<Border.LayoutTransform>
<RotateTransform Angle="-90"/>
</Border.LayoutTransform>
<ContentPresenter ContentSource="Header" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</Border>
<ContentPresenter Grid.RowSpan="2" Grid.Row="1" Margin="{TemplateBinding Padding}" Grid.Column="2" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
<Border BorderBrush="White" BorderThickness="{TemplateBinding BorderThickness}" Grid.RowSpan="4" CornerRadius="4" Grid.Column="1" Grid.ColumnSpan="3">
<Border.OpacityMask>
<MultiBinding ConverterParameter="7" Converter="{StaticResource BorderGapMaskConverter}">
<Binding ElementName="Header" Path="ActualWidth"/>
<Binding Path="ActualWidth" RelativeSource="{RelativeSource Self}"/>
<Binding Path="ActualHeight" RelativeSource="{RelativeSource Self}"/>
</MultiBinding>
</Border.OpacityMask>
<Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="3">
<Border BorderBrush="White" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="2"/>
</Border>
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<GroupBox Header="Hello world!" Margin="12" Style="{DynamicResource GroupBoxStyle1}"/>
</Window>
И модифицированный преобразователь выглядит следующим образом
// Type: System.Windows.Controls.BorderGapMaskConverter
// Assembly: PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35
// Assembly location: C:\Windows\Microsoft.NET\assembly\GAC_MSIL\PresentationFramework\v4.0_4.0.0.0__31bf3856ad364e35\PresentationFramework.dll
using System;
using System.Globalization;
using System.Runtime;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Media;
using System.Windows.Shapes;
namespace WfpApplication1 //System.Windows.Controls
{
public class LeftBorderGapMaskConverter : IMultiValueConverter
{
[TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
public LeftBorderGapMaskConverter()
{
// base.ctor();
}
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
Type type1 = typeof(double);
if (parameter == null
|| values == null
|| (values.Length != 3 || values[0] == null)
|| (values[1] == null
|| values[2] == null
|| (!type1.IsAssignableFrom(values[0].GetType())
|| !type1.IsAssignableFrom(values[1].GetType())))
|| !type1.IsAssignableFrom(values[2].GetType()))
return DependencyProperty.UnsetValue;
Type type2 = parameter.GetType();
if (!type1.IsAssignableFrom(type2)
&& !typeof(string).IsAssignableFrom(type2))
return DependencyProperty.UnsetValue;
double pixels1 = (double)values[0];
double num1 = (double)values[1];
double num2 = (double)values[2];
if (num1 == 0.0 || num2 == 0.0)
return (object)null;
double pixels2 = !(parameter is string)
? (double)parameter
: double.Parse((string)parameter, (IFormatProvider)NumberFormatInfo.InvariantInfo);
Grid grid = new Grid();
grid.Width = num1;
grid.Height = num2;
RowDefinition RowDefinition1 = new RowDefinition();
RowDefinition RowDefinition2 = new RowDefinition();
RowDefinition RowDefinition3 = new RowDefinition();
RowDefinition1.Height = new GridLength(pixels2);
RowDefinition2.Height = new GridLength(pixels1);
RowDefinition3.Height = new GridLength(1.0, GridUnitType.Star);
grid.RowDefinitions.Add(RowDefinition1);
grid.RowDefinitions.Add(RowDefinition2);
grid.RowDefinitions.Add(RowDefinition3);
ColumnDefinition ColumnDefinition1 = new ColumnDefinition();
ColumnDefinition ColumnDefinition2 = new ColumnDefinition();
ColumnDefinition1.Width = new GridLength(num2/2.0);
ColumnDefinition2.Width = new GridLength(1.0, GridUnitType.Star);
grid.ColumnDefinitions.Add(ColumnDefinition1);
grid.ColumnDefinitions.Add(ColumnDefinition2);
Rectangle rectangle1 = new Rectangle();
Rectangle rectangle2 = new Rectangle();
Rectangle rectangle3 = new Rectangle();
rectangle1.Fill = (Brush)Brushes.Black;
rectangle2.Fill = (Brush)Brushes.Black;
rectangle3.Fill = (Brush)Brushes.Black;
Grid.SetColumnSpan((UIElement)rectangle1, 2);
Grid.SetColumn((UIElement)rectangle1, 0);
Grid.SetRow((UIElement)rectangle1, 0);
Grid.SetColumn((UIElement)rectangle2, 1);
Grid.SetRow((UIElement)rectangle2, 1);
Grid.SetColumnSpan((UIElement)rectangle3, 2);
Grid.SetColumn((UIElement)rectangle3, 0);
Grid.SetRow((UIElement)rectangle3, 2);
grid.Children.Add((UIElement)rectangle1);
grid.Children.Add((UIElement)rectangle2);
grid.Children.Add((UIElement)rectangle3);
return (object)new VisualBrush((Visual)grid);
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
return new object[1]
{
Binding.DoNothing
};
}
}
}
Спасибо за код, да, я буду работать над уменьшением белой полосы, в противном случае это выглядит не так. – wonea
Вы можете полностью удалить белый экран, удалив все внутри. –
AlSki
Спасибо, мне нужно выяснить, как нарисовать текст над линией, т. Е. Изменить порядок розыгрыша. – wonea