0

コントロールを含むグループボックスをWPFで作成していますが、ヘッダーを水平方向ではなく垂直方向に実行するように変更できるかどうか疑問に思っていましたか?これが私のコードです。

<GroupBox Grid.Column="0">
    <GroupBox.Header>
        Navigation
    </GroupBox.Header>
    <StackPanel Orientation="Vertical" >
        <Button>Up</Button>
        <Button>Down</Button>
    </StackPanel>
</GroupBox>

プロパティを調べましたが、GroupBox.Header要素に含まれるTextBlockを変更する以外に何も見つからないようです。

<GroupBox Grid.Column="0">
    <GroupBox.Header>
        <Orientation>
           <!-- Invalid -->
        </Orientation>
    </GroupBox.Header>
    <StackPanel Orientation="Vertical" >
        <Button>Up</Button>
        <Button>Down</Button>
    </StackPanel>
</GroupBox>
4

3 に答える 3

1

グループ ボックスの垂直ヘッダーの 2 つのオプションを想像できます。

1)テキストブロックの「フロー」を回転させますが、文字は回転させません

2) テキストブロック自体を回転させる

XAML の 2 つのオプションを次に示します。

    <Grid>
        <Grid.Resources>
            <System:String x:Key="header">Vertical</System:String>
        </Grid.Resources>
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition />
        </Grid.RowDefinitions>
        <GroupBox Grid.Row="0">
            <GroupBox.HeaderTemplate>
                <DataTemplate>
                    <ItemsControl ItemsSource="{StaticResource header}" />
                </DataTemplate>
            </GroupBox.HeaderTemplate>
        </GroupBox>
        <GroupBox Grid.Row="1">
            <GroupBox.HeaderTemplate>
                <DataTemplate>
                    <TextBlock Text="{StaticResource header}">
                        <TextBlock.LayoutTransform>
                            <RotateTransform Angle="90"  />
                        </TextBlock.LayoutTransform>
                    </TextBlock>
                </DataTemplate>
            </GroupBox.HeaderTemplate>
        </GroupBox>
    </Grid>
于 2012-09-25T12:10:41.853 に答える
1

できますが、きれいではありません。 不適切に回転されたヘッダー

<GroupBox>
    <GroupBox.Header>
        <TextBlock Text="Hello">
            <TextBlock.RenderTransform>
                 <RotateTransform Angle="90" CenterX="0" CenterY="0"  /> 
            </TextBlock.RenderTransform>
        </TextBlock>
    </GroupBox.Header>
  <TextBlock Text="World!"/>
</GroupBox>

これをサポートするには、GroupBoxのスタイルも変更する必要があります。

これは、いくつかの行、いくつかのコンテンツ プレゼンター、およびいくつかの境界線を含む単なるグリッドのように見えるので、それを列に変換してそこから移動できるはずです。実際には、ヘッダーを実行する ContentPresenter に Rotate を配置するので、好きな場所にスタイルを適用できます。

最終更新

標準コントロールからテンプレートを抽出することにより、テンプレートを変更してヘッダーを丸くすることができますが、境界線をマスクするために使用されるコンバーターがあることもわかります。逆コンパイラ (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
          };
    }
}
}
于 2012-09-25T12:52:01.677 に答える
1

プロパティを変更したり、ヘッダー テンプレートを使用したりするだけでは、グループ ボックス ヘッダーを垂直方向に実行できるとは思えません。代わりに を試すことができますがRotateTransform、グループ ボックス内のすべての要素も同様に回転します。そのため、グループ ボックス内のコンテナー要素に対して個別にカウンター変換を行う必要があります。

<GroupBox Header="Navigation" Grid.Column="0">
    <GroupBox.RenderTransform>
        <RotateTransform Angle="-90" CenterX="100" CenterY="100" />
    </GroupBox.RenderTransform>
    <StackPanel Orientation="Vertical">
        <StackPanel.RenderTransform>
            <RotateTransform Angle="90" CenterX="100" CenterY="100"  />
        </StackPanel.RenderTransform>
        <Button>Up</Button>
        <Button>Down</Button>
    </StackPanel>
</GroupBox>

要素を整列させるのは面倒で、一日中プロパティをいじる必要がありますCenterXCenterYしかし、それがあなたが望むものなら、これがそれを手に入れる方法だと思います:)

于 2012-09-25T11:17:18.107 に答える