2017-02-07 14 views
0

Я кодирую приложение с использованием 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?

ответ

3

Некоторые люди скажут вам, что ViewModel взаимодействует с моделью и видом, но я не являюсь одним из них.

Если вам нужно сделать чисто косметический и не зависит от каких-либо данных модели, я бы сказал, что вы должны обращаться с ним исключительно в представлении и его кодовомзади.

Наличие таких данных только для просмотра в режиме просмотра помешает, и если ваш взгляд немного сложный, он может стать довольно ужасным. Это, для меня, любопытное поражение точки разделения всех слоев и сохранения все как можно чище.

+0

Благодарим вас за ответ. Похоже, я просто не могу найти преимущества/недостатки для обоих решений из-за моего отсутствия опыта. Какой подход был бы лучше для обслуживания? Я знаю, что наличие ужасной viewmodel bc данных просмотра внутри не звучит хорошо, однако я знаю, что в коде нет ничего хорошего. Жесткое решение. – Crekate

+1

Code-behind - это не зло; его можно и нужно использовать, особенно в вашем случае, что является косметическим. То, что он не должен использовать, - это манипуляция данными, логика и общее все, что делает модель viewmodel. – Kilazur

+0

Еще раз спасибо, тогда я пойду для решения secund. – Crekate

1

Для меня ViewModel должен обрабатывать любую логику, связанную с данными. Например:

public class OrderViewModel 
{ 
    /* 
    Other fields and properties 
    */ 

    public decimal Total 
    { 
     get 
     { 
     return this.Price * this.Quantity; 
     } 
    } 
} 

Здесь ViewModel содержит логику для расчета общей стоимости заказа. Но никакого визуального представления НЕ должно быть здесь. Визуальное представление данных должно быть в представлении и нигде больше.

+0

Благодарим вас за ответ. Должна ли, например, фильтровать список, используя текст текстового поля, в коде или в режиме просмотра? Потому что это просто показывает, что я предполагаю, что это также должно произойти в коде. Правильно ли это? – Crekate

+0

Да, вы должны создать обработчик событий, когда пользователь вводит что-то в текстовое поле (или нажимает кнопку), чтобы отфильтровать элементы списка на основе введенного текста. –

 Смежные вопросы

  • Нет связанных вопросов^_^