[英]MVVM Manipulating the view, using code-behind or viewmodel
我正在使用MVVM對應用程序進行編碼,我有一個問題,是否應該使用代碼隱藏操作View或將其留空。 我想做的是,當用戶單擊一個按鈕時,一個隱藏的視圖就會滑出。 目前,我正在視圖模型中執行此操作。 這是我的代碼:
這是我的觀點:
<Window.DataContext>
<ViewModels:MainWindowViewModel/>
</Window.DataContext>
<Window.Resources>
<Style x:Key="DockPanelStyle" TargetType="{x:Type DockPanel}" >
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="Background" Value="AliceBlue"/>
<Style.Triggers>
<DataTrigger
Binding="{Binding showView}"
Value="true">
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<ThicknessAnimation
Storyboard.TargetProperty="Margin"
To="0,0,0,0"
AccelerationRatio=".25"
DecelerationRatio=".25"
Duration="0:0:0.5"
/>
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<ThicknessAnimation
Storyboard.TargetProperty="Margin"
To="0,0,-400,0"
DecelerationRatio=".25"
AccelerationRatio=".25"
Duration="0:0:0.5"
/>
</Storyboard>
</BeginStoryboard>
</DataTrigger.ExitActions>
</DataTrigger>
</Style.Triggers>
</Style>
</Window.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<StackPanel
Grid.Column="0">
<Label Content="Main view" HorizontalAlignment="Center" FontSize="42"/>
<Button Command="{Binding SlideOutCommand}" Content="Show view" FontSize="42"/>
</StackPanel>
<DockPanel
Grid.Column="1"
Margin="0,0,-400,0"
Style="{StaticResource DockPanelStyle}">
<Label Content="Sliding view" HorizontalAlignment="Center" FontSize="42"/>
</DockPanel>
</Grid>
</Window>
后面的代碼為空。 這是我的ViewModel:
public class MainWindowViewModel : INotifyPropertyChanged
{
public MainWindowViewModel()
{
showView = false;
}
public ICommand SlideOutCommand
{
get { return new ActionCommand(action => ShowView()); }
}
private void ShowView()
{
showView = true;
//Do some extra logic
}
private bool _showView;
public bool showView
{
get { return _showView; }
set
{
_showView = value;
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
virtual protected void OnPropertyChanged([CallerMemberName]string propName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName));
}
}
還是應該采用這樣的解決方案:
視圖:
<Window.DataContext>
<ViewModels:MainWindowViewModel/>
</Window.DataContext>
<Window.Resources>
<Style x:Key="DockPanelStyle" TargetType="{x:Type DockPanel}" >
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="Background" Value="AliceBlue"/>
<Style.Triggers>
<DataTrigger
Binding="{Binding Path=Tag, RelativeSource={RelativeSource Self}}"
Value="true">
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<ThicknessAnimation
Storyboard.TargetProperty="Margin"
To="0,0,0,0"
AccelerationRatio=".25"
DecelerationRatio=".25"
Duration="0:0:0.5"
/>
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<ThicknessAnimation
Storyboard.TargetProperty="Margin"
To="0,0,-400,0"
DecelerationRatio=".25"
AccelerationRatio=".25"
Duration="0:0:0.5"
/>
</Storyboard>
</BeginStoryboard>
</DataTrigger.ExitActions>
</DataTrigger>
</Style.Triggers>
</Style>
</Window.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<StackPanel
Grid.Column="0">
<Label Content="Main view" HorizontalAlignment="Center" FontSize="42"/>
<Button Command="{Binding SlideOutCommand}" Content="Show view" FontSize="42" Click="Button_Click"/>
</StackPanel>
<DockPanel
x:Name="SlideView"
Grid.Column="1"
Margin="0,0,-400,0"
Style="{StaticResource DockPanelStyle}"
Tag="{Binding Path=showView,RelativeSource={RelativeSource AncestorType=Window}}">
<Label Content="Sliding view" HorizontalAlignment="Center" FontSize="42"/>
</DockPanel>
</Grid>
</Window>
代碼隱藏:
public partial class MainWindowView : Window, INotifyPropertyChanged
{
public MainWindowView()
{
InitializeComponent();
showView = false;
}
private void Button_Click(object sender, RoutedEventArgs e)
{
showView = true;
}
private bool _showView;
public bool showView
{
get { return _showView; }
set
{
_showView = value;
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
virtual protected void OnPropertyChanged([CallerMemberName]string propName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName));
}
}
和ViewModel:
public class MainWindowViewModel : INotifyPropertyChanged
{
public MainWindowViewModel()
{
}
public ICommand SlideOutCommand
{
get { return new ActionCommand(action => ShowView()); }
}
private void ShowView()
{
//Do some extra logic
}
public event PropertyChangedEventHandler PropertyChanged;
virtual protected void OnPropertyChanged([CallerMemberName]string propName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName));
}
}
MVVM模式中更好的方法是什么?
有人會告訴您ViewModel與模型和視圖進行交互,但我不是其中之一。
如果您要做的只是純粹的修飾,並且不依賴於任何模型數據,那么我想您應該僅在視圖及其背后的代碼中對其進行處理。
在視圖模型中擁有這些僅視圖數據會使其雜亂無章,如果您的視圖有點復雜,它可能會變得非常可怕。 對我而言,這有點使分離所有圖層並保持所有內容盡可能干凈的觀點失敗了。
對我來說,ViewModel應該處理與數據有關的任何邏輯。 例如:
public class OrderViewModel
{
/*
Other fields and properties
*/
public decimal Total
{
get
{
return this.Price * this.Quantity;
}
}
}
在此,ViewModel包含用於計算訂單總價的邏輯。 但是任何視覺表示都不應在這里。 數據的視覺表示應位於“視圖”中,且無其他位置。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.