簡體   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