Я кодирую приложение с использованием MVVM, и у меня возникает вопрос, следует ли мне манипулировать View с использованием кода или я должен оставить его пустым. Что я хочу сделать, когда пользователь нажимает кнопку, скрывается скрытый вид. На данный момент я делаю это на виду. Вот мой код:MVVM Манипулирование представлением с использованием кода или схемы просмотра
Это мой Вид:
<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>
Code-за пустой. Это мой 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>
Code-за:
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 bc данных просмотра внутри не звучит хорошо, однако я знаю, что в коде нет ничего хорошего. Жесткое решение. – Crekate
Code-behind - это не зло; его можно и нужно использовать, особенно в вашем случае, что является косметическим. То, что он не должен использовать, - это манипуляция данными, логика и общее все, что делает модель viewmodel. – Kilazur
Еще раз спасибо, тогда я пойду для решения secund. – Crekate