2010-07-18 38 views
8

Tôi có cửa sổ chính WPF ít cửa sổ hơn. Tôi đang cố gắng tạo nó để người dùng cuối có thể kéo cửa sổ.Cách tạo cửa sổ WPF không cửa sổ có thể kéo được mà không nhận được InvalidOperationException

Tôi đã thêm dòng sau vào constructor của Window:

this.MouseLeftButtonDown += delegate { DragMove(); }; 

Vấn đề là, tôi có một hộp thoại mở ra với hai nút. Khi tôi nhấp vào một trong các nút này, tôi nhận được một InvalidOperationException bị hủy bỏ với thông báo "Chỉ có thể gọi DragMove khi nút chuột chính bị hỏng".

Điều này đặt ra một số câu hỏi: Tại sao sự kiện được tổ chức trong hộp thoại có liên quan đến điều này? Tôi làm cách nào để thực hiện điều này mà không có ngoại lệ này?

Cảm ơn!

+0

Tôi cũng có ít cửa sổ viền hơn với các nút và cho phép người dùng kéo cửa sổ bằng cách nhấn nút chuột trái và nó hoạt động tốt. Vui lòng cung cấp mẫu mã tối thiểu nhưng hoàn chỉnh cho biết hành vi này. –

Trả lời

7

Cách 'chính xác' để tạo cửa sổ không biên giới có thể di chuyển là trả lại HTCAPTION trong thông báo WM_NCHITTEST. Các mã sau đây cho thấy làm thế nào để làm điều đó. Lưu ý rằng bạn sẽ muốn trả lại HTCLIENT nếu con trỏ trên một số phần tử trực quan của Window, vì vậy mã này chỉ là để bạn bắt đầu.

http://msdn.microsoft.com/en-us/library/ms645618(VS.85).aspx

public partial class Window1 : Window 
{ 
    public Window1() 
    { 
     InitializeComponent(); 
    } 

    protected override void OnSourceInitialized(EventArgs e) 
    { 
     HwndSource hwndSource = (HwndSource)HwndSource.FromVisual(this); 
     hwndSource.AddHook(WndProcHook); 
     base.OnSourceInitialized(e); 
    } 

    private static IntPtr WndProcHook(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handeled) 
    { 
     if (msg == 0x0084) // WM_NCHITTEST 
     { 
      handeled = true; 
      return (IntPtr)2; // HTCAPTION 
     } 
     return IntPtr.Zero; 
    } 
} 
+0

Nếu bạn cố gắng "trả lại HTCAPTION trong tin nhắn WM_NCHITTEST" như Tergiver gợi ý, thì các nút sẽ không thể nhấp được, tức là sự kiện nhấp sẽ không hoạt động đối với các nút. Có ai có một workaround cho điều này? –

+0

Lưu ý rằng tôi đã nói rằng mã đó chỉ là điểm khởi đầu. Bạn không thể trả về HTCAPTION cho toàn bộ hình chữ nhật của cửa sổ của bạn như mã bên trên. Bạn phải quyết định khu vực nào trong cửa sổ của bạn không được là khu vực 'chú thích'. Điều này có thể đơn giản như một hình chữ nhật trong khu vực điều khiển của bạn, hoặc phức tạp như đi bộ trên cây thị giác và tìm kiếm các điều khiển. – Tergiver

0

Có một dự án Microsoft để xử lý tất cả các "cửa sổ" phong cách và nhiều hơn nữa, và nó là mã nguồn mở, bạn có thể muốn có một cái nhìn tại http://code.msdn.microsoft.com/WPFShell. Tôi đang sử dụng ứng dụng tài chính thương mại và chưa gặp phải bất kỳ sự cố nào trên bất kỳ phiên bản cửa sổ nào.

1

Đặt MouseDown atrribute của cửa sổ hoặc bất kỳ kiểm soát khác mà bạn muốn sử dụng:

<TextBlock Grid.Column="0" HorizontalAlignment="Stretch" MouseLeftButtonDown="TextBlock_MouseLeftButtonDown" >Handy Dandy</TextBlock> 

Và thực hiện nó trong mã đằng sau như thế này:

private void TextBlock_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) 
{ 
    this.DragMove(); 
} 

Từ: http://www2.suddenelfilio.net/2007/01/19/wpf-draggable-windowless-windows/

0

bạn có thể ghi đè phương thức gốc:

public new void DragMove() 
    { 
     if (this.WindowState == WindowState.Normal) 
     { 
      SendMessage(hs.Handle, WM_SYSCOMMAND, (IntPtr)0xf012, IntPtr.Zero); 
      SendMessage(hs.Handle, WM_LBUTTONUP, IntPtr.Zero, IntPtr.Zero); 
     } 
    } 
Các vấn đề liên quan