C# MVVM使用代码隐藏或viewmodel操纵视图
我正在使用MVVM编写应用程序,我有一个问题,是应该使用代码来操纵视图,还是应该将其留空。我想做的是,当用户单击一个按钮时,隐藏的视图会滑出。目前,我正在视图模型中进行此操作。这是我的密码: 我的看法是:C# MVVM使用代码隐藏或viewmodel操纵视图,c#,wpf,xaml,mvvm,C#,Wpf,Xaml,Mvvm,我正在使用MVVM编写应用程序,我有一个问题,是应该使用代码来操纵视图,还是应该将其留空。我想做的是,当用户单击一个按钮时,隐藏的视图会滑出。目前,我正在视图模型中进行此操作。这是我的密码: 我的看法是: <Window.DataContext> <ViewModels:MainWindowViewModel/> </Window.DataContext> <Window.Resources> <Sty
<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>
或者我应该采用这样的解决方案:
视图:
和视图模型:
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));
}
}
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中有这种仅视图的数据会使它变得混乱,如果您的视图有点复杂,它可能会变得非常可怕。对我来说,这有点违背了分离所有层并保持尽可能干净的观点。有些人会告诉你ViewModel与模型和视图交互,但我不是其中之一 如果您所要做的只是表面的,不依赖于任何模型数据,那么我认为您应该只在视图及其代码中处理它
在viewmodel中有这种仅视图的数据会使它变得混乱,如果您的视图有点复杂,它可能会变得非常可怕。对我来说,这有点违背了分离所有层并尽可能保持所有内容干净的原则。对我来说,ViewModel应该处理与数据相关的任何逻辑。 例如:
public class OrderViewModel
{
/*
Other fields and properties
*/
public decimal Total
{
get
{
return this.Price * this.Quantity;
}
}
}
这里,ViewModel包含用于计算订单总价的逻辑。但任何视觉表现都不应该出现在这里。
数据的可视表示应该在视图中,而不是其他地方。对于我来说,ViewModel应该处理与数据相关的任何逻辑。 例如:
public class OrderViewModel
{
/*
Other fields and properties
*/
public decimal Total
{
get
{
return this.Price * this.Quantity;
}
}
}
这里,ViewModel包含用于计算订单总价的逻辑。但任何视觉表现都不应该出现在这里。
数据的可视表示应该在视图中,而不是其他位置。谢谢您的回答。由于缺乏经验,我似乎无法找到两种解决方案的优点/缺点。哪种方法更适合维护?我知道在里面有可怕的视图数据视图模型bc听起来不太好,但我知道后面的代码中并没有任何东西。硬决策。代码隐藏不是邪恶的;它可以也应该使用,特别是在你的情况下,这是一个化妆品之一。它不应该用于数据操作、逻辑和viewmodel所做的所有事情。再次感谢您,我将选择secund解决方案。需要考虑的一些事情:1)代码背后无法轻松进行单元测试。2) 如果不重新执行逻辑,就不能用其他视图替换视图。3) 如果您需要扩展功能性,您可能会在视图中进行扩展,而不是重构所有内容,从而使设计更不易维护。好的,但是我希望后面的代码只关注视图,比如单击按钮后滑动一些控件。即使在viewmodel中,它也不可测试。对于第一种方法,viewmodel有一个仅用于在视图中显示控件的属性,因此如果我更改视图,我将有一个视图模型,该视图模型的属性在任何情况下都不会使用,因为它仅与视图相关。我应该关心这个吗?谢谢你的回答。看起来我只是找不到两种解决方案的优势/缺点,因为我缺乏经验。哪种方法更适合维护?我知道在里面有可怕的视图数据视图模型bc听起来不太好,但我知道后面的代码中并没有任何东西。硬决策。代码隐藏不是邪恶的;它可以也应该使用,特别是在你的情况下,这是一个化妆品之一。它不应该用于数据操作、逻辑和viewmodel所做的所有事情。再次感谢您,我将选择secund解决方案。需要考虑的一些事情:1)代码背后无法轻松进行单元测试。2) 如果不重新执行逻辑,就不能用其他视图替换视图。3) 如果您需要扩展功能性,您可能会在视图中进行扩展,而不是重构所有内容,从而使设计更不易维护。好的,但是我希望后面的代码只关注视图,比如单击按钮后滑动一些控件。即使在viewmodel中,它也不可测试。对于第一种方法,viewmodel有一个仅用于在视图中显示控件的属性,因此如果我更改视图,我将有一个视图模型,该视图模型的属性在任何情况下都不会使用,因为它仅与视图相关。我应该关心这个吗?谢谢你的回答。例如,是否应该在代码behinde或viewmodel中使用文本框文本过滤列表?因为它只是为了显示,所以我假设它也应该发生在代码后面。是否正确?是的,当用户在文本框中输入内容(或单击按钮)时,您应该创建一个事件处理程序,以根据输入的文本筛选列表项。谢谢您的回答。例如,是否应该在代码behinde或viewmodel中使用文本框文本过滤列表?因为它只是为了显示,所以我假设它也应该发生在代码后面。是否正确?是的,当用户在文本框中输入内容(或单击按钮)时,您应该创建一个事件处理程序,以根据输入的文本过滤列表项。
public class OrderViewModel
{
/*
Other fields and properties
*/
public decimal Total
{
get
{
return this.Price * this.Quantity;
}
}
}