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.