2014-12-08 20 views
2

투명 사각형이있는 창을 만들려고합니다. 사용자가 원하는대로 크기를 조정할 수 있기를 원합니다. 이 코드는 수직 및 수평 재 크기 여기대각선에서 그리드 분배기가 작동합니까?

<Window x:Class="TransparentWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="PloofTAS" Height="355" Width="539" Topmost="True" 
     ResizeMode="NoResize" 
     AllowsTransparency="True" 
     Background="Transparent" 
     WindowStyle="None" MouseLeftButtonDown="Window_MouseLeftButtonDown"> 

    <Grid Name="GlobalGrid"> 
     <Grid.RowDefinitions> 
      <RowDefinition Height="*" /> 
      <RowDefinition Height="8" /> 
      <RowDefinition Height="*" /> 
      <RowDefinition Height="8" /> 
      <RowDefinition Height="*" /> 
     </Grid.RowDefinitions> 
     <Grid.ColumnDefinitions> 
      <ColumnDefinition Width="*" /> 
      <ColumnDefinition Width="8" /> 
      <ColumnDefinition Width="*" /> 
      <ColumnDefinition Width="8" /> 
      <ColumnDefinition Width="*" /> 
     </Grid.ColumnDefinitions> 
     <Rectangle Fill="Gray" Grid.Column="0" Grid.RowSpan="5" /> 
     <Rectangle Fill="Gray" Grid.Column="4" Grid.RowSpan="5" /> 
     <Rectangle Fill="Gray" Grid.Column="1" Grid.Row="0" Grid.ColumnSpan="3" /> 
     <Rectangle Fill="Gray" Grid.Column="1" Grid.Row="4" Grid.ColumnSpan="3" /> 
     <GridSplitter Grid.Column="2" Grid.Row="1" Height="Auto" HorizontalAlignment="Stretch" /> 
     <GridSplitter Grid.Column="1" Grid.Row="2" Height="Auto" HorizontalAlignment="Stretch" /> 
     <GridSplitter Grid.Column="3" Grid.Row="2" Height="Auto" HorizontalAlignment="Stretch" /> 
     <GridSplitter Grid.Column="2" Grid.Row="3" Height="Auto" HorizontalAlignment="Stretch" /> 
     <Rectangle Fill="Orange" Grid.Row="1" Grid.Column="1" /> 
     <Rectangle Fill="Orange" Grid.Row="1" Grid.Column="3" /> 
     <Rectangle Fill="Orange" Grid.Row="3" Grid.Column="1" /> 
     <Rectangle Fill="Orange" Grid.Row="3" Grid.Column="3" /> 
     <Rectangle Fill="Transparent" Stroke="Red" Grid.Column="2" Grid.Row="2"/> 
    </Grid> 
</Window> 

을 위해 노력하면 결과 창

에게 있습니다 There is no need to compile the code ^_^

나는 주황색 사각형 (레드/투명 사각형의 모서리)에 대한 싶습니다

대각선으로 또는 수직과 수평으로 모두 작업 할 수 있어야합니다. 가능한가?

답변

1

GridSplitter를 프로그래밍 방식으로 설정할 수 없으므로이 문제에 대한 우아한 해결책을 모르겠습니다.

내 솔루션은 마우스의 움직임에 따라 열 및 행 측정을 설정하는 것만으로 더러운 캡처 일뿐입니다.

스타일 및 이벤트를 설정하십시오. 코드에서 변경할 행 및 열의 속성 저장소 인덱스를 태그 지정합니다. rectangle.Tag 속성에 저장된 값에 따라

private bool _isMouseCaptured; 

    public MainWindow() 
    { 
     InitializeComponent(); 
    } 

    private void UIElement_OnMouseDown(object sender, MouseButtonEventArgs e) 
    { 
     var uiElement = sender as UIElement; 
     if (uiElement == null) 
      return; 

     if (uiElement.CaptureMouse()) 
      _isMouseCaptured = true; 
    } 

    private void UIElement_OnMouseMove(object sender, MouseEventArgs e) 
    { 
     if (!_isMouseCaptured) 
      return; 

     var clientWindow = Content as FrameworkElement; 
     if (clientWindow == null) 
      return; 

     var rectangle = sender as Rectangle; 
     if (rectangle == null) 
      return; 

     Point position = Mouse.GetPosition(GlobalGrid); ; 

     if (position.X < 0 || position.Y < 0 || position.X > clientWindow.ActualWidth || position.Y > clientWindow.ActualHeight) 
      return; 

     GridUpdate(position, rectangle, clientWindow); 
    } 

    private void UIElement_OnMouseUp(object sender, MouseButtonEventArgs e) 
    { 
     if (!_isMouseCaptured) 
      return; 

     var uiElement = sender as UIElement; 
     if (uiElement == null) 
      return; 

     uiElement.ReleaseMouseCapture(); 
    } 

    private void UIElement_OnLostMouseCapture(object sender, MouseEventArgs e) 
    { 
     _isMouseCaptured = false; 
    } 

크기 조정 그리드의 열과 행 :

<Window.Resources> 
    <Style x:Key="DiagonalSplitterRectangle" TargetType="{x:Type Rectangle}"> 
     <Setter Property="Fill" Value="Orange"/> 
     <EventSetter Event="MouseDown" Handler="UIElement_OnMouseDown"/> 
     <EventSetter Event="MouseMove" Handler="UIElement_OnMouseMove"/> 
     <EventSetter Event="MouseUp" Handler="UIElement_OnMouseUp"/> 
     <EventSetter Event="LostMouseCapture" Handler="UIElement_OnLostMouseCapture"/> 
    </Style> 
</Window.Resources> 

    <Rectangle Grid.Row="1" Grid.Column="1" Style="{StaticResource DiagonalSplitterRectangle}" Tag="0,0"/> 
    <Rectangle Grid.Row="1" Grid.Column="3" Style="{StaticResource DiagonalSplitterRectangle}" Tag="0,4"/> 
    <Rectangle Grid.Row="3" Grid.Column="1" Style="{StaticResource DiagonalSplitterRectangle}" Tag="4,0"/> 
    <Rectangle Grid.Row="3" Grid.Column="3" Style="{StaticResource DiagonalSplitterRectangle}" Tag="4,4"/> 

간단한 마우스 캡처 이벤트. 맞은 행 및 행 측정 값을 변경하려면 올바른 동작이 필요했습니다.

private void GridUpdate(Point position, Rectangle rectangle, FrameworkElement clientWindow) 
    { 
     var gridPosition = new GridPosition(rectangle.Tag.ToString()); 
     var oppositeGridPosition = GetOppositeGridPosition(gridPosition); 

     var rowHeight = GetMeasure(gridPosition.Row, position.Y, clientWindow.ActualHeight); 
     var columnWidth = GetMeasure(gridPosition.Column, position.X, clientWindow.ActualWidth); 

     var oppositeRowHeight = GlobalGrid.RowDefinitions[oppositeGridPosition.Row].ActualHeight; 
     var oppositeColumnWidth = GlobalGrid.ColumnDefinitions[oppositeGridPosition.Column].ActualWidth; 

     GlobalGrid.RowDefinitions[gridPosition.Row].Height = new GridLength(rowHeight); 
     GlobalGrid.ColumnDefinitions[gridPosition.Column].Width = new GridLength(columnWidth); 

     GlobalGrid.RowDefinitions[oppositeGridPosition.Row].Height = new GridLength(oppositeRowHeight); 
     GlobalGrid.ColumnDefinitions[oppositeGridPosition.Column].Width = new GridLength(oppositeColumnWidth); 
    } 

    private GridPosition GetOppositeGridPosition(GridPosition gridPosition) 
    { 
     var row = (gridPosition.Row == 0) ? 4 : 0; 
     var column = (gridPosition.Column == 0) ? 4 : 0; 

     return new GridPosition(row, column); 
    } 

    private double GetMeasure(int gridPosition, double position, double windowMeasure) 
    { 
     return gridPosition == 0 ? position : windowMeasure - position; 
    } 

GridPosition은 열과 행 인덱스 값을 저장하는 구조입니다.

public struct GridPosition 
{ 
    public int Row { get; private set; } 
    public int Column { get; private set; } 

    public GridPosition(int row, int column) 
     : this() 
    { 
     Row = row; 
     Column = column; 
    } 

    public GridPosition(string gridPostion) 
     : this() 
    { 
     Row = Convert.ToInt32(gridPostion.Split(',')[0]); 
     Column = Convert.ToInt32(gridPostion.Split(',')[1]); 
    } 
} 
+0

답변을 주셔서 감사합니다. 뷰에 많은 코드가 포함되어 있으며 태그를 문서화해야하기 때문에 여전히 우아하지 않다고 말한 것입니다. 만약 내가 이것을 위해, 나는 오히려 그것을 새로운 컨트롤로 구현 –