Ograniczam właściwość "WindowState" mojego głównego okna do mojego ViewModel w celu zmiany stanu okna za pomocą polecenia, ale po raz pierwszy zminimalizuję okno minimalizuje się tak, jak robi to arkusz roboczy w pliku Excel. Czy istnieje jakieś obejście tego problemu lub poprawny sposób powiązania właściwości "WindowState" z moim ViewModel, aby okno było minimalizowane poprawnie?Powiązanie właściwości "WindowState" okna w WPF przy użyciu MVVM
Odpowiedz
Nie sądzę, należy dbać o stan okna w modelu widoku, to jest całkowicie błędne, ponieważ warstwa niższego szczebla jest świadoma wyższy -poziom warstwy (w związku z tym nieprawidłowe rozróżnianie obaw (SOC)).
To, co normalnie robię w tym przypadku, to subskrybowanie zmian w modelu widoku z poziomu kodu kontrolki lub okna (czyli widoku) zawierającego model widoku. W tym przypadku ważne jest, aby pisać kod z tyłu kodu, ponieważ jest on używany tylko w widoku (a zatem kod z tyłu jest idealną lokalizacją dla tej logiki, której naprawdę nie chcesz testować jednostkowo).
Chociaż jest to generalnie prawdziwe, możliwe jest również, że model widoku eksponuje właściwość niezwiązaną z 'WindowState', która powinna dyktować jej wartość. Na przykład jeden z moich modeli widoku zawierał Boolean 'ShowResults'. Chciałem to przełączać moje 'WindowState' na' Maximize', więc stworzyłem BoolToWindowStateConverter. – Pakman
To jest przykładowa praca wokół tego testowanego z Relaying Command Logic. Więcej informacji uzyskasz pod numerem 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>
aw 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");
}
}
}
Inną opcją do rozważenia jest subskrypcji zarówno poprzez polecenie i wydarzenia na kod związany, np:
<Button Command="{Binding SnoozeCommand}" Click="Button_Click">Snooze</Button>
Polecenie w tym przypadku wpływa na VM. Zdarzenie Click zmienia tylko stan okna.
Co masz do tej pory? Opublikuj kod. – decyclone
Bez znajomości tła tego, co próbujesz zrobić, wygląda na to, że możesz zająć krok w ViewModelu o krok za daleko. Rzeczy, które są wyłącznie logiką UI, są całkowicie akceptowalne w kodzie źródłowym i w rzeczywistości nie mają żadnego biznesu w ViewModelu. Powiedziałbym, że obejmuje to rzeczy takie jak fokus i stan okna. – Josh
@Josh Enstein Przełączam się za pomocą kodu, jak powiedziałeś, teraz działa idealnie. Próbuję ukryć przycisk paska zadań po zminimalizowaniu okna i użyć elementu menu dołączonego do ikony na pasku zadań, aby przywrócić okno. – norlando