我正在尝试在其中放置一个透明方块的窗口,我希望允许用户以他/她想要的任何方式重新调整大小。此代码适用于垂直和水平重新调整大小
<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>
以下是生成的窗口
我希望橙色方块(红色/透明方块的角落)能够对角工作,或垂直和水平工作。有可能吗?
答案 0 :(得分:1)
我不知道这个问题的优雅解决方案,因为无法以编程方式设置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]);
}
}