Binding the “WindowState” property of a window in WPF using MVVM

后端 未结 3 1028
盖世英雄少女心
盖世英雄少女心 2021-01-12 06:01

I bound the \"WindowState\" property of my main window to my ViewModel in order to change the state of the window by a command, but the first time I minimize the window it m

相关标签:
3条回答
  • 2021-01-12 06:24

    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).

    0 讨论(0)
  • 2021-01-12 06:25

    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");
                }
            }
        }
    
    0 讨论(0)
  • 2021-01-12 06:25

    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.

    0 讨论(0)
提交回复
热议问题