繁体   English   中英

MVVM使用代码隐藏或viewmodel操作视图

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM