WPF / XAML: как определить размер окна без границы?
Я использую окно без границы и сам рисую хром. Я хочу изменить размер окна типичным образом и определить сетку 3x3 с центром, являющимся содержимым, и внешними ячейками, составляющими соответствующие области, требующие различной обработки (TopLeft/TopMiddle/TopRight... так далее.) например курсоры. Максимизация, минимизация, перемещение и т. д. Все прямо вперед, но я мог бы использовать некоторые указатели для изменения размера в разных направлениях на основе ячейки, над которой курсор.
2 ответов
Это, кажется, довольно плотно. Минимальная / максимальная ширина и высота учтены так же, как переменные borderwidths. Единственная проблема, о которой я знаю, - это когда движение курсора быстрое, а размер находится в пределах 20 пиксов от минуты, когда он немного прилипает из-за частоты обновления. Ничего особенного, но я разберусь.
alt текст http://cartesia.pbworks.com/f/1265489984/Resize.png
Кажется, я не могу правильно отобразить тег окна...(Просто выньте Апостроф и все должно быть хорошо. У кого-нибудь есть мысли?
XAML
<'Window x:Class="Article_1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
Title="Article_1_Resizing"
Background="Transparent" AllowsTransparency="True"
WindowStyle="None" WindowStartupLocation="CenterScreen"
MinHeight="100" Height="400" MaxHeight="600"
MinWidth="100" Width="400" MaxWidth="800">
<Window.Resources>
<SolidColorBrush x:Key="Brush_ChromeBackground" Color="#FFC8D1E0"/>
<SolidColorBrush x:Key="Brush_ChromeBorder" Color="#FFA0A0A0"/>
<sys:Double x:Key="Chrome_BorderWidth">5</sys:Double>
</Window.Resources>
<Border x:Name="Border_Chrome"
BorderBrush="{StaticResource Brush_ChromeBorder}" BorderThickness="1,1,1,1"
CornerRadius="2,2,2,2"
Width="Auto">
<Grid x:Name="Grid" ShowGridLines="False">
<Grid.RowDefinitions>
<RowDefinition x:Name="row_Top" Height="Auto"/>
<RowDefinition x:Name="row_Middle" Height="*"/>
<RowDefinition x:Name="row_Bottom" Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="col_Left" Width="Auto"/>
<ColumnDefinition x:Name="col_Middle" Width="*"/>
<ColumnDefinition x:Name="col_Right" Width="Auto"/>
</Grid.ColumnDefinitions>
<!-- Top Row -->
<Rectangle x:Name="Rectangle_TopLeft"
Grid.Row="0" Grid.Column="0"
Width="{StaticResource Chrome_BorderWidth}" Height="{StaticResource Chrome_BorderWidth}"
Fill="{StaticResource Brush_ChromeBackground}"
Cursor="SizeNWSE"
MouseLeftButtonDown="Resize_Begin" MouseLeftButtonUp="Resize_End"
MouseMove="Resize"/>
<Rectangle x:Name="Rectangle_TopMiddle"
Grid.Row="0" Grid.Column="1"
Height="{StaticResource Chrome_BorderWidth}"
Fill="{StaticResource Brush_ChromeBackground}"
Cursor="SizeNS"
MouseLeftButtonDown="Resize_Begin" MouseLeftButtonUp="Resize_End"
MouseMove="Resize"/>
<Rectangle x:Name="Rectangle_TopRight"
Grid.Row="0" Grid.Column="2"
Width="{StaticResource Chrome_BorderWidth}" Height="{StaticResource Chrome_BorderWidth}"
Fill="{StaticResource Brush_ChromeBackground}"
Cursor="SizeNESW"
MouseLeftButtonDown="Resize_Begin" MouseLeftButtonUp="Resize_End"
MouseMove="Resize"/>
<!-- Middle Row -->
<Rectangle x:Name="Rectangle_MiddleLeft"
Grid.Row="1" Grid.Column="0"
Width="{StaticResource Chrome_BorderWidth}"
Fill="{StaticResource Brush_ChromeBackground}"
Cursor="SizeWE"
MouseLeftButtonDown="Resize_Begin" MouseLeftButtonUp="Resize_End"
MouseMove="Resize"/>
<!-- Content -->
<Label Content="Mouse Down to Move - Double Click to Close"
Grid.Row="1" Grid.Column="1"
Background="White" Foreground="Black"
HorizontalAlignment="Stretch" HorizontalContentAlignment="Center"
VerticalAlignment="Stretch" VerticalContentAlignment="Center"
MouseDoubleClick="_Close"
MouseLeftButtonDown="Move"/>
<Rectangle x:Name="Rectangle_MiddleRight"
Grid.Row="1" Grid.Column="2"
Width="{StaticResource Chrome_BorderWidth}"
Fill="{StaticResource Brush_ChromeBackground}"
Cursor="SizeWE"
MouseLeftButtonDown="Resize_Begin" MouseLeftButtonUp="Resize_End"
MouseMove="Resize"/>
<!-- Bottom Row -->
<Rectangle x:Name="Rectangle_BottomLeft"
Grid.Row="2" Grid.Column="0"
Width="{StaticResource Chrome_BorderWidth}" Height="{StaticResource Chrome_BorderWidth}"
Fill="{StaticResource Brush_ChromeBackground}"
Cursor="SizeNESW"
MouseLeftButtonDown="Resize_Begin" MouseLeftButtonUp="Resize_End"
MouseMove="Resize"/>
<Rectangle x:Name="Rectangle_BottomMiddle"
Grid.Row="2" Grid.Column="1"
Height="{StaticResource Chrome_BorderWidth}"
Fill="{StaticResource Brush_ChromeBackground}"
Cursor="SizeNS"
MouseLeftButtonDown="Resize_Begin" MouseLeftButtonUp="Resize_End"
MouseMove="Resize"/>
<Rectangle x:Name="Rectangle_BottomRight"
Grid.Row="2" Grid.Column="2"
Width="{StaticResource Chrome_BorderWidth}" Height="{StaticResource Chrome_BorderWidth}"
Fill="{StaticResource Brush_ChromeBackground}"
Cursor="SizeNWSE"
MouseLeftButtonDown="Resize_Begin" MouseLeftButtonUp="Resize_End"
MouseMove="Resize"/>
</Grid>
</Border>
</Window>
Код
Partial Public Class Article_1
Public Sub New()
InitializeComponent()
Initialize_Sizes
End Sub
Private isResizing as Boolean = False
Private Const CURSOR_OFFSET_SMALL As Double = 3
Private Const CURSOR_OFFSET_LARGE As Double = 5
Private _x As Double = 0
Private _Y As Double = 0
Private Sub Initialize_Sizes
Dim _MinWidth As Double = Rectangle_MiddleLeft.Width + _
Rectangle_BottomRight.Width + _
border_Chrome.BorderThickness.Left + _
border_Chrome.BorderThickness.Right + 1
If MinWidth < _MinWidth then _
MinWidth = _MinWidth
Dim _MinHeight As Double = Rectangle_TopMiddle.Height + _
Rectangle_BottomMiddle.Height + _
border_Chrome.BorderThickness.top + _
border_Chrome.BorderThickness.Bottom + 1
If MinHeight < _MinHeight then _
MinHeight = _MinHeight
End Sub
Private sub Resize_Begin(sender as object, _
e As MouseEventArgs)
isResizing = True
DirectCast(sender, Rectangle).CaptureMouse
End Sub
Private sub Resize_End(sender as object, _
e As MouseEventArgs)
isResizing = False
DirectCast(sender, Rectangle).ReleaseMouseCapture
End Sub
Private Sub Resize(sender As Object, _
e As MouseEventArgs)
If isResizing = False then Exit Sub
_x = e.GetPosition(me).x
_y = e.GetPosition(me).Y
Select Case DirectCast(sender, Rectangle).Name
Case "Rectangle_TopLeft" : Resize_Width_Left
Resize_Height_Top
Case "Rectangle_TopMiddle" : Resize_Height_Top
Case "Rectangle_TopRight" : Resize_Width_Right
Resize_Height_Top
Case "Rectangle_MiddleLeft" : Resize_Width_Left
Case "Rectangle_MiddleRight" : Resize_Width_Right
Case "Rectangle_BottomLeft" : Resize_Width_Left
Resize_Height_Bottom
Case "Rectangle_BottomMiddle" : Resize_Height_Bottom
Case "Rectangle_BottomRight" : Resize_Width_Right
Resize_Height_Bottom
Case else : MessageBox.Show("Error in Resize")
End Select
End Sub
Private Sub Resize_Width_Left
_x -= CURSOR_OFFSET_SMALL
If Width - _x >= MinWidth Then
If Width - _x <= MaxWidth then
Width -= _x
Left += _x
End If
End If
End Sub
Private Sub Resize_Width_Right
_x += CURSOR_OFFSET_LARGE
Select Case _x
Case Is < MinWidth : width = MinWidth
Case Is > MaxWidth : Width = MaxWidth
Case Else : Width = _x
End Select
End Sub
Private Sub Resize_Height_Top
_y -= CURSOR_OFFSET_SMALL
If Height - _y >= MinHeight Then
If Height - _y <= MaxHeight then
Height -= _y
Top += _y
End If
End If
End Sub
Private Sub Resize_Height_Bottom
_y += CURSOR_OFFSET_SMALL
Select Case _y
Case Is < MinHeight : Height = MinHeight
Case Is > MaxHeight : Height = MaxHeight
Case Else : Height = _y
End Select
End Sub
Private Sub Move(ByVal sender As Object, _
ByVal e As System.Windows.Input.MouseButtonEventArgs)
Dim curs As Cursor = Cursor
Cursor = Cursors.SizeAll
DragMove()
Cursor = Curs
End Sub
Private Sub _Close()
Close
End Sub
End Class
для минималистского подхода,
- установите цвет Brush_ChromeBackground в "прозрачный". Это делает прямоугольники перетаскивания невидимыми.
- установите для ResizeMode окна значение "NoResize". Это скрывает серый скошенный край вокруг окна, оставляя только 1px Border_Chrome.
кроме того, я перевел код на C#:
public partial class Article_1 : Window
{
private bool _isResizing = false;
private const double CURSOR_OFFSET_SMALL = 3;
private const double CURSOR_OFFSET_LARGE = 5;
public Article_1()
{
InitializeComponent();
MinWidth = Math.Max(MinWidth, Rectangle_MiddleLeft.Width + Rectangle_MiddleRight.Width + 10);
MinHeight = Math.Max(MinHeight, Rectangle_TopMiddle.Height + Rectangle_BottomMiddle.Height + 10);
}
private void Resize_Begin(object sender, MouseButtonEventArgs e)
{
if (sender is Rectangle)
{
_isResizing = true;
((Rectangle)sender).CaptureMouse();
}
}
private void Resize_End(object sender, MouseButtonEventArgs e)
{
if (sender is Rectangle)
{
_isResizing = false;
((Rectangle)sender).ReleaseMouseCapture();
}
}
private void Resize(object sender, MouseEventArgs e)
{
if (_isResizing && (sender is Rectangle))
{
double x = e.GetPosition(this).X;
double y = e.GetPosition(this).Y;
string mode = ((Rectangle)sender).Name.ToLower();
if (mode.Contains("left"))
{
x -= CURSOR_OFFSET_SMALL;
if ((Width - x >= MinWidth) && (Width - x <= MaxWidth))
{
Width -= x;
Left += x;
}
}
if (mode.Contains("right"))
{
Width = Math.Max(MinWidth, Math.Min(MaxWidth, x + CURSOR_OFFSET_LARGE));
}
if (mode.Contains("top"))
{
y -= CURSOR_OFFSET_SMALL;
if ((Height - y >= MinHeight) && (Height - y <= MaxHeight))
{
Height -= y;
Top += y;
}
}
if (mode.Contains("bottom"))
{
Height = Math.Max(MinHeight, Math.Min(MaxHeight, y + CURSOR_OFFSET_SMALL));
}
}
}
private void Move(object sender, MouseButtonEventArgs e)
{
Cursor old = Cursor;
Cursor = Cursors.SizeAll;
DragMove();
Cursor = old;
}
private void Close(object sender, MouseButtonEventArgs e)
{
Close();
}
}