Làm cách nào để xóa thu nhỏ và phóng to khỏi cửa sổ có thể thay đổi kích thước trong WPF?


80

WPF không cung cấp khả năng có một cửa sổ cho phép thay đổi kích thước nhưng không có các nút phóng to hoặc thu nhỏ. Tôi muốn có thể tạo một cửa sổ như vậy để tôi có thể có các hộp thoại có thể thay đổi kích thước.

Tôi biết giải pháp sẽ có nghĩa là sử dụng pinvoke nhưng tôi không chắc phải gọi cái gì và làm thế nào. Một tìm kiếm trên pinvoke.net không tìm ra bất kỳ thứ gì khiến tôi phải ngạc nhiên khi tôi cần, chủ yếu là tôi chắc chắn vì Windows Forms cung cấp các thuộc tính CanMinimizeCanMaximizetrên cửa sổ của nó.

Ai đó có thể chỉ cho tôi hoặc cung cấp mã (ưu tiên C #) về cách thực hiện việc này không?

Câu trả lời:


113

Tôi đã đánh cắp một số mã mà tôi tìm thấy trên diễn đàn MSDN và tạo một phương thức mở rộng trên lớp Window, như sau:

internal static class WindowExtensions
{
    // from winuser.h
    private const int GWL_STYLE      = -16,
                      WS_MAXIMIZEBOX = 0x10000,
                      WS_MINIMIZEBOX = 0x20000;

    [DllImport("user32.dll")]
    extern private static int GetWindowLong(IntPtr hwnd, int index);

    [DllImport("user32.dll")]
    extern private static int SetWindowLong(IntPtr hwnd, int index, int value);

    internal static void HideMinimizeAndMaximizeButtons(this Window window)
    {
        IntPtr hwnd = new System.Windows.Interop.WindowInteropHelper(window).Handle;
        var currentStyle = GetWindowLong(hwnd, GWL_STYLE);

        SetWindowLong(hwnd, GWL_STYLE, (currentStyle & ~WS_MAXIMIZEBOX & ~WS_MINIMIZEBOX));
    }
}

Điều khác duy nhất cần nhớ là vì một số lý do, điều này không hoạt động từ phương thức khởi tạo của cửa sổ. Tôi đã giải quyết vấn đề đó bằng cách đưa cái này vào hàm tạo:

this.SourceInitialized += (x, y) =>
{
    this.HideMinimizeAndMaximizeButtons();
};

Hi vọng điêu nay co ich!


3
Một đoạn mã đẹp hơn trong Window: ghi đè được bảo vệ void OnSourceInitialized (EventArgs e) {base.OnSourceInitialized (e); this.HideMinimizeAndMaximizeButtons (); }
Dmitry Shechtman

1
Tại sao không làm cho nó đơn giản hơn và đăng ký sự kiện SourceInitialized ngay trong phương thức HideMinimizeAndMaximizeButtons ()? Sau đó, bạn có thể gọi phương thức từ phương thức khởi tạo và không phải gọi bất cứ thứ gì khác.
jmatthias

1
giải pháp này không bao gồm việc nhấp đúp vào thanh tiêu đề.
Lonli-Lokli

1
Lưu ý Phục sinh! Phương thức này phải được đưa vào sự kiện Windows Loaded vì xử lý không được xác định trong sự kiện Khởi tạo.
SezMe 19/03/18

4
Sau tất cả thời gian biết rằng chức năng này hiện diện trong các biểu mẫu cửa sổ, tôi chỉ không hiểu rằng microsoft đã không đưa loại chức năng này vào WPF ngay từ đầu. Thành thật mà nói, hộp thoại có hộp thu nhỏ và sách phóng to trông không chuyên nghiệp và việc nhấp đúp vào thanh chú thích cũng là vấn đề tương tự. Xin lỗi làm giảm bớt sự thất vọng của tôi về WPF một chút, nó rất tốt và có tài sản chuỗi nhưng thỉnh thoảng bạn lại vấp phải thứ gì đó đơn giản nhưng cuối cùng lại không.
Philip Stuyck

91

Một cách là thiết lập của bạn ResizeMode="NoResize". Nó sẽ hoạt động như thế này. nhập mô tả hình ảnh ở đây

Tôi hi vọng cái này giúp được!


32
Điều này sẽ làm cho cửa sổ không thể thay đổi kích thước, điều này hoàn toàn trái ngược với câu hỏi.
Mashmagar

5
Nói chung, những người google tìm cách vô hiệu hóa các nút thu nhỏ và tối đa hóa không có yêu cầu cụ thể về việc cửa sổ có thể thay đổi kích thước. Hiện tại, đây là kết quả hàng đầu cho truy vấn "thu nhỏ cửa sổ wpf vô hiệu hóa" và câu trả lời này trả lời chính xác câu hỏi. Bất chấp điều đó, thật xấu hổ khi MS đã không tạo thanh tiêu đề hoặc toàn bộ cửa sổ chrome là "chỉ một điều khiển hoặc thuộc tính khác". Quá nhiều di sản từ '90 ...
Hoàng đế Orionii

2
Trong trường hợp này, các phần tử có độ rộng động (ví dụ: DockPanel) vẫn có thể thay đổi kích thước cửa sổ. Nhưng không phải là người dùng nữa. Vì vậy, tùy chọn này thực sự đáp ứng yêu cầu của tôi.
OneWorld

3
Không trả lời các câu hỏi, nhưng hữu ích cho tôi. Cảm ơn.
dkantowitz

@EmpasterOrionii mặc dù tại thời điểm trang này có thể là kết quả hàng đầu của Google, nhưng không có cách nào ngụ ý rằng câu trả lời này là tốt nhất khi bạn cho rằng câu trả lời này không giải quyết "Làm cách nào để loại bỏ thu nhỏ và tối đa hóa khỏi a resizable windowtrong WPF?" khi nó loại bỏ những "thay đổi kích thước" khía cạnh từ sản phẩm đã hoàn thành. Điều đó giống như giúp ai đó muốn sơn xe của họ màu đỏ và trong quá trình này bạn tháo động cơ.
MickyD

22

Không biết nếu điều này làm việc cho yêu cầu của bạn. trực quan .. Đây là

<Window x:Class="DataBinding.MyWindow" ...Title="MyWindow" Height="300" Width="300" 
    WindowStyle="ToolWindow" ResizeMode="CanResizeWithGrip">

3
Điều này gần như hoạt động, nhưng vẫn có thể phóng to hoặc thu nhỏ cửa sổ nếu bạn nhấp đúp vào thanh tiêu đề, nhấp chuột phải và sử dụng menu điều khiển hoặc nút trên thanh tác vụ nếu nó có sẵn. Thêm vào đó, tất nhiên nó trông giống như một cửa sổ công cụ chứ không phải một cửa sổ bình thường.
Nidonocu

Đúng ... nhưng sau đó IMHO một lần nữa ràng buộc có vẻ kỳ lạ là người dùng không được phép phóng to nhưng có thể kéo-phóng to cửa sổ theo cách thủ công bằng cách thay đổi kích thước. Nhưng đó là cửa sổ của bạn .. các quy tắc của bạn :)
Gishu

điều này có thể hữu ích cho các trường hợp mà MaxWidthvà / hoặc MaxHeightcửa sổ đã được thiết lập.
Brett Ryan

6

Nếu bất cứ ai sử dụng cửa sổ Devexpress (DXWindow), câu trả lời được chấp nhận không hoạt động. Một cách tiếp cận xấu xí là

public partial class MyAwesomeWindow : DXWindow
{
    public MyAwesomeWIndow()
    {
       Loaded += OnLoaded;
    }

    private void OnLoaded(object sender, RoutedEventArgs routedEventArgs)
    {
        // hides maximize button            
        Button button = (Button)DevExpress.Xpf.Core.Native.LayoutHelper.FindElementByName(this, DXWindow.ButtonParts.PART_Maximize.ToString());
        button.IsHitTestVisible = false;
        button.Opacity = 0;

        // hides minimize button
        button = (Button)DevExpress.Xpf.Core.Native.LayoutHelper.FindElementByName(this, DXWindow.ButtonParts.PART_Minimize.ToString());
        button.IsHitTestVisible = false;
        button.Opacity = 0;

        // hides close button
        button = (Button)DevExpress.Xpf.Core.Native.LayoutHelper.FindElementByName(this, DXWindow.ButtonParts.PART_CloseButton.ToString());
        button.IsHitTestVisible = false;
        button.Opacity = 0;
    } 
}

Tôi có lẽ đã đọc năm bài viết khác nhau trước khi tôi nhận thấy câu trả lời của bạn ở đây. Điều này không hiệu quả, nhưng yuck. Bạn đã bao giờ tìm thấy một cách tốt hơn?
DonBoitnott

3

Đây là một giải pháp tôi đang sử dụng. Lưu ý rằng nút phóng to vẫn hiển thị.

Đánh dấu:

<Window x:Class="Example"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Example"
        StateChanged="Window_StateChanged">

Mã ẩn:

// Disable maximizing this window
private void Window_StateChanged(object sender, EventArgs e)
{
    if (this.WindowState == WindowState.Maximized)
        this.WindowState = WindowState.Normal;
}

1
Anh ta hỏi làm thế nào để ẩn các nút nhưng vẫn giữ nguyên chức năng.
Alexandru Dicu,

Ở mức tối thiểu, cửa sổ đang nhấp nháy. Không tốt lắm.
Mugen

2

Bạn có thể đặt ResizeMode = "NoResize" của cửa sổ nếu bạn muốn loại bỏ nút Thu nhỏ và Phóng to


Ehh nhưng sau đó bạn không thể thay đổi kích thước nó sẽ có thể
Karsten

0

Biến thể này của giải pháp do @MattHamilton đề xuất có thể (và phải) được gọi trong phương thức khởi tạo của Window. Bí quyết là đăng ký một đại biểu cho SourceInitializedsự kiện trong phương thức mở rộng.

private const int GWL_STYLE = -16, WS_MAXIMIZEBOX = 0x10000, WS_MINIMIZEBOX = 0x20000;

[DllImport("user32.dll")]
extern private static int GetWindowLong(IntPtr hwnd, int index);

[DllImport("user32.dll")]
extern private static int SetWindowLong(IntPtr hwnd, int index, int value);

/// <summary>
/// Hides the Minimize and Maximize buttons in a Window. Must be called in the constructor.
/// </summary>
/// <param name="window">The Window whose Minimize/Maximize buttons will be hidden.</param>
public static void HideMinimizeAndMaximizeButtons(this Window window)
{
    window.SourceInitialized += (s, e) => {
        IntPtr hwnd = new System.Windows.Interop.WindowInteropHelper(window).Handle;
        int currentStyle = GetWindowLong(hwnd, GWL_STYLE);

        SetWindowLong(hwnd, GWL_STYLE, currentStyle & ~WS_MAXIMIZEBOX & ~WS_MINIMIZEBOX);
    };
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.