2013-07-31 16 views
11

Mi piacerebbe sapere come disattivare (non rimuovere/nascondere) il pulsante Chiudi in una finestra WPF. Io so come nasconderlo, che rende la finestra barra del titolo simile a questa:Disabilitare pulsante Chiudi nella barra del titolo di una finestra WPF (C#)

enter image description here

ma voglio disabilitarlo che significa che dovrebbe essere simile a questo:

enter image description here

Sono scripting in C# e utilizzo di WPF (Windows Presentation Foundation).

+0

ho trovato questo link vedere se questo [link] [1] può aiutare: [1]: http://stackoverflow.com/questions/743906/how-to-hide-close-button-i n-WPF-finestra – Vishal

risposta

16

Prova questo:

public partial class MainWindow : Window 
{ 

    [DllImport("user32.dll")] 
    static extern IntPtr GetSystemMenu(IntPtr hWnd, bool bRevert); 
    [DllImport("user32.dll")] 
    static extern bool EnableMenuItem(IntPtr hMenu, uint uIDEnableItem, uint uEnable); 



    const uint MF_BYCOMMAND = 0x00000000; 
    const uint MF_GRAYED = 0x00000001; 
    const uint MF_ENABLED = 0x00000000; 

    const uint SC_CLOSE = 0xF060; 

    const int WM_SHOWWINDOW = 0x00000018; 
    const int WM_CLOSE = 0x10; 

    public MainWindow() 
    { 
     InitializeComponent(); 
    } 

    private void Window_Loaded(object sender, RoutedEventArgs e) 
    { 

    } 

    protected override void OnSourceInitialized(EventArgs e) 
    { 
     base.OnSourceInitialized(e); 

     HwndSource hwndSource = PresentationSource.FromVisual(this) as HwndSource; 

     if (hwndSource != null) 
     { 
      hwndSource.AddHook(new HwndSourceHook(this.hwndSourceHook)); 
     } 
    } 


    IntPtr hwndSourceHook(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) 
    { 
     if (msg == WM_SHOWWINDOW) 
     { 
      IntPtr hMenu = GetSystemMenu(hwnd, false); 
      if (hMenu != IntPtr.Zero) 
      { 
       EnableMenuItem(hMenu, SC_CLOSE, MF_BYCOMMAND | MF_GRAYED); 
      } 
     } 
     else if (msg == WM_CLOSE) 
     { 
      handled = true; 
     } 
     return IntPtr.Zero; 
    } 
} 

(Tratto da qui: http://blogs.microsoft.co.il/blogs/tamir/archive/2007/09/26/never-ever-close-me-how-to-disable-close-button-in-wpf.aspx)

assicurarsi di impostare la ResizeMode-NoResize.

+1

Suggerisco che 'else if (msg == WM_CLOSE) { gestito = true; }' viene omesso poiché ciò impedirà la chiusura della finestra a livello di programmazione. – Hans

3

si deve ignorare e in OnCLosing evento impostato e.Cancel = true

public MyWindow() 
{ 
    InitializeComponent(); 
    this.Closing += new System.ComponentModel.CancelEventHandler(MyWindow_Closing); 
} 

void MyWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e) 
{ 
    e.Cancel = true; 
} 
+2

Questo non rende pulsante sembrare che sia disattivato. –

+0

Sì, ma voglio disabilitare in realtà il pulsante Chiudi invece di fare Cancellare la chiusura. – Bubbled86

+0

Ho paura che puoi solo nascondere o eseguire l'override in WPF, per favore dai un'occhiata a questo http://stackoverflow.com/questions/743906/how-to-hide-close-button-in-wpf-window – Rohit

1

Probabilmente si può farlo con win32 aggiustamenti.

L'ho fatto in questo modo: Ottieni CustomChromeWindow (che alla fine assomiglierà esattamente a quello in figura), e legherai solo la proprietà Command() a viewmodel, e quindi imposta CanExecuteCommand = false, che renderà il pulsante disabilitato (How does one "disable" a button in WPF using the MVVM pattern?).

Ci potrebbe me in questo modo troppo: How to disable close button on a window in another process with C++?

In sostanza, chiamare quel codice con PInvoke. È possibile ottenere facilmente l'handle di finestra WPF.

1

This post che una risposta utilizzando Behavior, GetWindowLong e SetWindowLong:

public class HideCloseButtonOnWindow : System.Windows.Interactivity.Behavior<Window> 
{ 
    #region bunch of native methods 

    private const int GWL_STYLE = -16; 
    private const int WS_SYSMENU = 0x80000; 

    [DllImport("user32.dll", SetLastError = true)] 
    private static extern int GetWindowLong(IntPtr hWnd, int nIndex); 

    [DllImport("user32.dll")] 
    private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong); 

    #endregion 

    protected override void OnAttached() 
    { 
     base.OnAttached(); 
     AssociatedObject.Loaded += OnLoaded; 
    } 

    protected override void OnDetaching() 
    { 
     AssociatedObject.Loaded -= OnLoaded; 
     base.OnDetaching(); 
    } 

    private void OnLoaded(object sender, RoutedEventArgs e) 
    { 
     var hwnd = new System.Windows.Interop.WindowInteropHelper(AssociatedObject).Handle; 
     SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) & ~WS_SYSMENU); 
    } 
} 

Come si usa:

<Window x:Class="WpfApplication2.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" 
    xmlns:w="clr-namespace:WpfApplication2"> 

<i:Interaction.Behaviors> 
    <w:HideCloseButtonOnWindow /> 
</i:Interaction.Behaviors> 

</Window> 
Problemi correlati