Binding the "WindowState" property of a window in WPF using MVVM Binding the "WindowState" property of a window in WPF using MVVM wpf wpf

Binding the "WindowState" property of a window in WPF using MVVM


this is a sample work around that tested with Relaying Command Logic. You will get more detail on WPF Apps With The Model-View-ViewModel Design Pattern .

<Window x:Class="WpfMvvmTestCSharp.Window1"    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"    xmlns:vm="clr-namespace:WpfMvvmTestCSharp"    Title="Window1" Height="300" Width="300" WindowState="{Binding CurWindowState, Mode=TwoWay}">    <Window.DataContext>        <vm:Window1ViewModel/>    </Window.DataContext>    <Grid>        <Button Command="{Binding CmdMax}" Height="23" Margin="12,25,0,0" Name="button1" VerticalAlignment="Top" HorizontalAlignment="Left" Width="75">Maximize</Button>        <Button Command="{Binding CmdMin}" Height="23" Margin="101,25,102,0" Name="button2" VerticalAlignment="Top">Minimize</Button>        <Button Command="{Binding CmdRes}" Height="23" HorizontalAlignment="Right" Margin="0,25,13,0" Name="button3" VerticalAlignment="Top" Width="75">Restore</Button>    </Grid></Window>

and in the Windows ViewModel

class Window1ViewModel:ViewModelBase    {        public Window1ViewModel()        {            CurWindowState = WindowState.Maximized;        }        public ICommand CmdMax        {            get { return new RelayCommand(param => onCmdMax()); }        }        void onCmdMax()        {            CurWindowState = WindowState.Maximized;        }        public ICommand CmdMin        {            get { return new RelayCommand(param => onCmdMin()); }        }        void onCmdMin()        {            CurWindowState = WindowState.Minimized;        }        public ICommand CmdRes        {            get { return new RelayCommand(param => onCmdRes()); }        }        void onCmdRes()        {            CurWindowState = WindowState.Normal;        }        private WindowState _curWindowState;        public WindowState CurWindowState        {            get            {                return _curWindowState;            }            set            {                _curWindowState = value;                base.OnPropertyChanged("CurWindowState");            }        }    }


I don't think you should care about the window state in a view model, it's completely wrong because a lower-level layer is aware of a higher-level layer (thus wrong Separation of Concerns (SOC)).

What I normally do in this case is subscribe to changes in the view model from the code-behind of the control or window (thus the view) containing the view model. In this case, it is valid to write code in the code-behind because it is only used in the view (and thus the code-behind is the perfect location for this logic, which you really don't want to unit test).


Another option to consider is subscribing both via a command AND an event to code behind, e.g:

    <Button Command="{Binding SnoozeCommand}" Click="Button_Click">Snooze</Button>

The command in this case affects the VM. The Click event, only changes the Window state.