2011-01-12 11 views
5

ho legato il "WindowState" proprietà della mia finestra principale per il mio ViewModel al fine di modificare lo stato della finestra da un comando, ma la prima volta che minimizzare il finestra minimizza come fa un foglio di lavoro in un file Excel. C'è un modo per aggirare questo o un modo corretto per legare la proprietà "WindowState" al mio ViewModel in modo che la finestra si minimizzi correttamente?Binding il "WindowState" proprietà di una finestra in WPF utilizzando MVVM

+2

Cos'hai finora? Pubblica un po 'di codice. – decyclone

+4

Senza conoscere lo sfondo di ciò che stai cercando di fare, sembra che tu possa portare la cosa ViewModel ad un passo troppo lontano. Le cose che sono strettamente logiche dell'interfaccia utente sono completamente accettabili in code-behind e di fatto non hanno alcun business nel ViewModel. Direi che questo include cose come lo stato della messa a fuoco e della finestra. – Josh

+0

@Josh Enstein Passo a usare il codice come hai detto tu, ora funziona perfettamente. Quello che sto cercando di fare è nascondere il pulsante della barra delle applicazioni quando la finestra è ridotta a icona e utilizzare una voce di menu collegata all'icona della barra delle applicazioni per riportare la finestra. – norlando

risposta

6

Non credo che si dovrebbe preoccuparsi dello stato finestra in un modello di vista, è completamente sbagliato perché uno strato di livello inferiore è a conoscenza di un più alto livello di livello (quindi sbagliato Separation of Concerns (SOC)).

Cosa faccio di solito in questo caso è iscriviti ai cambiamenti del modello di vista dal code-behind del controllo o della finestra (in tal modo la vista) contenente il modello di vista. In questo caso, è valido per scrivere codice nel code-behind, perché viene utilizzato solo nella vista (e quindi il code-behind è il luogo perfetto per questa logica, che in realtà non si vuole test di unità).

+4

Mentre questo è vero in generale, è anche possibile per il modello al fine di esporre una proprietà estranei a 'WindowState' che dovrebbe dettare il suo valore. Ad esempio, uno dei miei modelli di visualizzazione conteneva il 'Boolean ShowResults'. Volevo che questo passasse il mio 'WindowState' a' Maximize', quindi ho creato un oggetto BoolToWindowStateConverter. – Pakman

13

questo è un lavoro del campione intorno a quello provato con Relaying Command Logic. Otterrete maggiori dettagli su 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> 

e nel 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

Un'altra opzione da considerare è la sottoscrizione sia tramite un comando e un evento al codice dietro, per esempio:

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

Il comando in questo caso colpisce la VM. L'evento Click, cambia solo lo stato della finestra.