gpt4 book ai didi

c# - Grid Splitter 在对角线上工作?

转载 作者:太空宇宙 更新时间:2023-11-03 13:13:49 25 4
gpt4 key购买 nike

我正在尝试制作一个内部有透明正方形的窗口,并且我希望允许用户以他/她想要的任何方式重新调整它的大小。此代码适用于垂直和水平调整大小

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

我希望橙色方 block (红色/透明方 block 的角)能够沿对角线或垂直和水平方向工作。可能吗?

最佳答案

我不知道这个问题的优雅解决方案,因为无法以编程方式设置 GridSplitter。

我的解决方案只是脏鼠标捕获并根据鼠标移动设置列和行度量。

设置样式和事件。我们将在后面的代码中更改的行和列的标记属性存储索引。

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

根据存储在 rectangle.Tag 属性中的值调整网格列和行的大小。对于正确的行为,也需要更改相反的列和行度量。

    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]);
}
}

关于c# - Grid Splitter 在对角线上工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27367624/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com