2012-09-25 2 views
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> 

답변

1

하지만 꽤하지 않습니다! Badly rotated header

<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을 수정해야 할 것입니다.

두 개의 행, 몇 개의 콘텐츠 발표자 및 몇 개의 테두리가있는 그리드처럼 보이므로이를 열로 바꾸고 거기에서 이동할 수 있어야합니다. 나는 실제로 Header를하는 ContentPresenter에 Rotate를 두었습니다. 그래서 당신이 원할 때마다 스타일을 적용 할 수 있습니다.

그러나 우리는 또한 주위의 경계를 마스크하는 데 사용되는 컨버터가있는 것을 발견, 우리는 라운드 헤더를 이동 수정할 수있는 표준 제어에서 템플릿을 추출하여 최종 업데이트

. 디 컴파일러 (DotPeek)를 사용하여 행과 열 둘레를 전환하여 갭을 측면으로 이동할 수도 있습니다.

Rotated GroupBox

그래서 템플릿이

<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 
      }; 
    } 
} 
} 
+0

코드를 보내 주셔서 감사합니다. 예, 그렇지 않으면 올바르게 보이지 않습니다. – wonea

+1

안에있는 모든 것을 제거하면 백그를 완전히 제거 할 수 있습니다. – AlSki

+0

감사합니다. 선 위에 텍스트를 그리는 방법, 즉 그리기 순서를 변경하는 방법을 알아야합니다. – wonea

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 특성 하루 종일 플레이해야 줘야 해.

1) TextBlock을하지만 돈 '의 "흐름"을 회전 : 만약 당신이 원하는 그러나 나는 이것이 그것이 내가 그룹 상자에 수직 헤더의 두 가지 옵션을 상상할 수

+0

아주 좋은 답변처럼 보이는,이 내부 회전 StackPanel의를 배치하고, 그 수 그 일을 할 것입니다. GroupBox를 동적으로 만드는 것은 까다로울 수 있습니다. – wonea

+0

요소가 그려지는 지점/구석을 변경할 수 있습니까?CenterX 또는 CenterY를 변경할 필요가 없습니까? – wonea

1

:) 얻을 수있는 방법입니다 생각 t는 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> 
+0

감사합니다. 첫 번째 GroupBox의 세로 문자가 마음에 듭니다. – wonea

관련 문제