How to disable and enable window close button [X] in MVVM?

Anto BAro 86 Reputation points
2022-02-22T15:41:03.053+00:00

Dear all,

I need to disable and enable the Windows [X] close button using the Binding (Mvvm).

How can I do ?

Best Regards

Windows Presentation Foundation
Windows Presentation Foundation
A part of the .NET Framework that provides a unified programming model for building line-of-business desktop applications on Windows.
2,778 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,940 questions
{count} votes

Accepted answer
  1. Hui Liu-MSFT 48,541 Reputation points Microsoft Vendor
    2022-02-23T09:00:54.377+00:00

    Here is an example of disabling and enabling the close button.
    MainWindow.xaml:

    <Grid>  
            <ToggleButton x:Name="tb" Width="100" Height="40"  Click="tb_Click">  
                <ToggleButton.Style>  
                    <Style TargetType="ToggleButton">  
                        <Style.Triggers>  
                            <Trigger Property="IsChecked" Value="True">  
                                <Setter Property="Content" Value="enable"/>  
                            </Trigger>  
                            <Trigger Property="IsChecked" Value="False">  
                                <Setter Property="Content" Value="disable"/>  
                            </Trigger>  
                        </Style.Triggers>  
                    </Style>  
                </ToggleButton.Style>  
            </ToggleButton>  
        </Grid>  
    

    MainWindow.xaml.cs:

    using System;  
    using System.Runtime.InteropServices;  
    using System.Windows;  
    using System.Windows.Controls.Primitives;  
    using System.Windows.Interop;  
      
    public partial class MainWindow : Window  
      {  
        public MainWindow()  
        {  
          InitializeComponent();  
        }  
        [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_GRAYED = 0x00000001;  
        const uint MF_ENABLED = 0x00000000;  
        const uint SC_CLOSE = 0xF060;  
          
        private void tb_Click(object sender, RoutedEventArgs e)  
        {  
          var tb = sender as ToggleButton;  
          if ((bool)tb.IsChecked)  
          {  
            var hwnd = new WindowInteropHelper(this).Handle;  
            IntPtr hMenu = GetSystemMenu(hwnd, false);  
            EnableMenuItem(hMenu, SC_CLOSE, MF_GRAYED);  
          }  
          else  
          {  
            var hwnd = new WindowInteropHelper(this).Handle;  
            IntPtr hMenu = GetSystemMenu(hwnd, false);  
            EnableMenuItem(hMenu, SC_CLOSE, MF_ENABLED);  
          }  
        }  
      }  
    

    The result:

    177152-13.gif

    Edit:

    public partial class MainWindow : Window  
      {   
        ViewModel vm ;  
        public MainWindow()  
        {  
          InitializeComponent();  
          vm=new ViewModel();  
          DataContext=vm;  
          this.Closing += new CancelEventHandler(Window_Closing);  
        }  
        void Window_Closing(object sender, CancelEventArgs e)  
        {  
          e.Cancel = (this.DataContext as ViewModel).ProcessWorking;  
        }  
      
        private void btn_Click(object sender, RoutedEventArgs e)  
        {  
          var tb = sender as ToggleButton;  
          if ((bool)tb.IsChecked)  
          {  
            vm.ProcessWorking = true;  
          }  
          else  
          {  
            vm.ProcessWorking = false;  
          }  
        }  
      }  
      public class ViewModel:INotifyPropertyChanged  
      {  
        private bool processWorking=false;  
        public bool ProcessWorking  
        {  
          get { return this.processWorking; }  
          set  
          {  
            this.processWorking=value;  
            OnPropertyChanged("ProcessWorking");  
          }  
        }  
        protected void OnPropertyChanged([CallerMemberName] string name = null)  
        {  
          PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));  
        }  
        public event PropertyChangedEventHandler PropertyChanged;  
      }  
    

    The result:
    177406-14.gif


    If the response is helpful, please click "Accept Answer" and upvote it.
    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    1 person found this answer helpful.

1 additional answer

Sort by: Most helpful
  1. Bruce (SqlWork.com) 65,396 Reputation points
    2022-02-22T22:39:18.637+00:00

    it would depend on the MVVM framework used.

    it requires an O/S call and the window handle to disable the window close button. also it is not recommended.

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.