WPF / XAML:如何调整没有边框的窗口大小?

时间:2010-01-21 18:12:53

标签: wpf xaml resize window border

我正在使用没有边框的窗口并自己绘制Chrome。我想以典型的方式调整窗口的大小,并定义了一个3x3网格,其中心是内容,外部单元格构成需要不同处理的各个区域(TopLeft / TopMiddle / TopRight ......等),如光标。最大化,最小化,移动等都是直截了当的,但我可以使用一些指针根据光标所在的单元格在各个方向上调整大小。

2 个答案:

答案 0 :(得分:6)

这看起来非常紧张。考虑最小/最大宽度和高度以及可变边界宽度。我知道的唯一问题是当光标移动很快并且尺寸在min的20像素范围内时,由于刷新率,它有点粘。不是很大,但我会对它进行排序。

alt text http://cartesia.pbworks.com/f/1265489984/Resize.png

我似乎无法正确显示Window标签...(只需取出撇号,它应该没问题。)任何人都有任何想法?

<强> 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

答案 1 :(得分:2)

对于极简主义的方法,

  1. 将Brush_ChromeBackground颜色设置为“透明”。这使得拖动矩形不可见。
  2. 将Window的ResizeMode设置为“NoResize”。这会隐藏窗口周围的灰色斜边,只留下1px Border_Chrome。
  3. 另外,我将代码隐藏转换为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();
        }
    }