2013-07-15 22 views
6

Tôi đang thiết kế cửa sổ tùy chỉnh của riêng mình trong WPF và tôi đã cố gắng triển khai chức năng thay đổi kích thước mà tôi đã sử dụng trước đó trong WinForms. Vì lý do nào đó, giá trị trả lại của WndProc của tôi không cho tôi kết quả đúng.WPF Borderless window resize

Tôi có một lớp NativeMethods cho tất cả các thư WndProc và kết quả của tôi:

public class NativeMethods 
{ 
    public const int WM_NCHITTEST = 0x84; 
    public const int HTCAPTION  = 2; 
    public const int HTLEFT  = 10; 
    public const int HTRIGHT  = 11; 
    public const int HTTOP   = 12; 
    public const int HTTOPLEFT  = 13; 
    public const int HTTOPRIGHT = 14; 
    public const int HTBOTTOM  = 15; 
    public const int HTBOTTOMLEFT = 16; 
    public const int HTBOTTOMRIGHT = 17; 
} 

Và đây là đoạn code sau cho cửa sổ của tôi:

public partial class MainWindow : Window 
{ 
    const int GripSize = 16; 
    const int BorderSize = 7; 

    public MainWindow() 
    { 
     InitializeComponent(); 
    } 

    protected override void OnSourceInitialized(EventArgs e) 
    { 
     base.OnSourceInitialized(e); 
     IntPtr windowHandle = new WindowInteropHelper(this).Handle; 
     HwndSource windowSource = HwndSource.FromHwnd(windowHandle); 
     windowSource.AddHook(WndProc); 
    } 

    private IntPtr WndProc(IntPtr hwnd, int msg, 
     IntPtr wParam, IntPtr lParam, ref bool handled) 
    { 
     if (msg == NativeMethods.WM_NCHITTEST) 
     { 
      int x = lParam.ToInt32() <<16>> 16, y = lParam.ToInt32() >> 16; 
      Point pos = PointFromScreen(new Point(x, y)); 

      if (pos.X > GripSize && 
       pos.X < ActualWidth - GripSize && 
       pos.Y >= ActualHeight - BorderSize) 
      { 
       return (IntPtr)NativeMethods.HTBOTTOM; // This doesn't work? 
      } 

      // Top, Left, Right, Corners, Etc. 
     } 

     return IntPtr.Zero; 
    } 
} 

tôi mong đợi con trỏ để thay đổi " thay đổi kích thước mũi tên xuống "và chức năng thay đổi kích thước để hoạt động như trong dự án WinForms của tôi. Tôi đã thiết lập các điểm ngắt và trả về HTBOTTOM đang kích hoạt khi con trỏ ở vị trí mong muốn. Trong XAML tôi đã đặt ResizeMode thành CanResize và WindowStyle được đặt thành None. Tôi đang làm gì sai?

+1

Tại sao không sử dụng 'ResizeMode =" CanResizeWithGrip "'? Bạn đang cố gắng để đạt được hiệu ứng này (chỉ để thay đổi kích thước nó xung quanh cửa sổ mà không có 'Grip')? –

+1

Bởi vì tôi vẫn muốn có thể thay đổi kích thước cửa sổ từ bất kỳ góc hoặc bên nào như chức năng bình thường. Tôi đã tìm ra vấn đề và tôi đang đăng câu trả lời ngay bây giờ. –

Trả lời

2

Đây là một sai lầm ngu ngốc. Tôi quên thêm handled = true; trước khi tôi trả lại kết quả. Bây giờ cửa sổ đang hoạt động như bình thường. Lưu ý nếu bạn đặt ResizeMode thành NoResize, mã này sẽ không hoạt động.

11

Có thể đơn giản là chỉ định WindowChrome. Theo nhận xét của bạn, bạn phải có thể thay đổi kích thước từ tất cả các cạnh cũng như sử dụng grip.Bạn có thể thực hiện tất cả điều này bằng cách đặt WindowStyle thành None và ResizeMode thành CanResizeWithGrip hoặc CanResize (bất kỳ điều gì bạn muốn đạt được)

<Window x:Class="MVVMProtoType.View.Test.Test" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
      Title="Test" Height="300" Width="300" WindowStyle="None" AllowsTransparency="False" ResizeMode="CanResizeWithGrip"> 

Trong mã này, bạn phải đặt Cửa sổ Chrome cho cửa sổ. Bạn có thể làm điều đó như thế này:

WindowChrome.SetWindowChrome(this, new WindowChrome()); 

HOẶC Bạn có thể sử dụng setter cho phong cách cửa sổ như:

<Setter Property="WindowChrome.WindowChrome"> 
     <Setter.Value> 
      <WindowChrome CornerRadius="0" GlassFrameThickness="1" UseAeroCaptionButtons="False"/> 
     </Setter.Value> 
</Setter> 

MSDN link for more information

Xin lưu ý lớp WindowChrome là một phần của .NET 4.5 Khung. For.NET 4,0 người dùng kiểm tra archive.msdn.microsoft.com/WPFShell

+1

Cảm ơn bạn đã phản hồi. Tôi không biết về không gian tên System.Windows.Shell mà có thể đã tiết kiệm cho tôi khá nhiều thời gian. –

2

Tôi đã viết một giải pháp trong một bài khác, bạn có thể thay đổi kích thước cửa sổ, bạn cần phải sử dụng .NET 4.5 hoặc WPFShell

Bạn cũng có thể đặt mã WindowChrome trực tiếp trên MainWindow.xaml của bạn như thế này, và nó hoạt động hoàn hảo mà không cần đặt một setter.

<Window x:Class="MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    xmlns:local="clr-namespace:Concursos" 
    mc:Ignorable="d" 
    Title="Concuros" Height="350" Width="525" 
    WindowStyle="None" 
    WindowState="Normal" 
    ResizeMode="CanResize" 
    > 
<WindowChrome.WindowChrome> 
    <WindowChrome 
     CaptionHeight="0" 
     ResizeBorderThickness="5" /> 
</WindowChrome.WindowChrome> 

    <Grid> 

    <YOUR CODE HERE 

</Grid> 

Bạn có thể vào đây để xem các bài hoàn chỉnh.

Solution

Đây là trước và sau khi

The Challenge The Solution