Как определить сводный вид с помощью MVVM в WP7?

#c# #silverlight #windows-phone-7 #mvvm #mvvm-light

#c# #silverlight #windows-phone-7 #mvvm #mvvm-light

Вопрос:

в принципе, у меня есть элемент управления pivot в моем приложении WP7, который содержит 3 вида. В каждом представлении я вызываю 1 из 3 моих разных веб-сервисов, которые я запускаю. Что я пытаюсь сделать, так это вызвать службу только тогда, когда они переходят к этому конкретному представлению.

Это довольно просто, используя код, лежащий в основе, потому что все, что вы делаете, это используете выбранный индекс с инструкцией switch, и вы можете соответствующим образом запускать определенные методы. Есть идеи о том, как выполнить это с помощью модели представления?

ПРИМЕЧАНИЕ: Я использую MVVM Light.

ОБНОВЛЕНИЕ: Вот мой код, который я обычно использую:

 private void PivotItem_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        int currentPivot = ResultsPivot.SelectedIndex;
        switch (currentPivot)
        {
            case 0:
                //Fire Method 1
                break;
            case 1:
                //Fire Method 2
                break;
            case 2:
                //Fire Method 3
                break;
            default:
                //Fire default method
                break;
        }
    }
  

Комментарии:

1. Покажите код, который вы пытаетесь преобразовать.

2. @Rick Я добавил код, который обычно использую.

Ответ №1:

Стандартный подход с MVVMLight заключается в разделении вашей модели представления на данные и команды. Большинство вещей, которые вы используете, связаны с привязкой данных, свойствами и т.д. Но команды на самом деле что-то делают.

В этом случае то, что вы вызываете «Метод запуска 1», является обычным методом, который для соответствия шаблону вы должны преобразовать в команду. Если у вас уже есть команды, вы понимаете, о чем я говорю.

Связующим элементом для событий, подобных SelectionChanged тем, которые вы бы подключили с помощью кода в MVVMLight, является EventToCommand фрагмент XAML, который вы помещаете в XAML с элементом pivot, а не в обработчик событий.

Итак, это шаблон: EventToCommand ваш ключ к подключению событий XAML к командам view-model без какого-либо кода. Лучшее, что можно сделать, это использовать образцы MVVMLight, чтобы увидеть, как EventToCommand работает, потому что есть много способов его использования.

Но вот простая версия:

 <controls:PivotItem Name="pivotItem">
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="SelectionChanged">
            <cmd:EventToCommand Command="{Binding SelectServiceCommand}"
                                CommandParameter="{Binding SelectedIndex, ElementName=pivotItem}"/>
        </i:EventTrigger>
        <!-- other stuff  -->
    </i:Interaction.Triggers>
</controls:PivotItem>
  

и чтобы заставить это работать, SelectServiceCommand должен фактически существовать в view-model, и он должен принимать параметр и делать правильные вещи для 0, 1, 2, 3 и т.д.

Ответ №2:

Это можно решить следующим образом

 <controls:Pivot x:Name="PivotControl"  FontSize="18"  >
        <Custom:Interaction.Triggers>
            <Custom:EventTrigger EventName="SelectionChanged">
                <GalaSoft_MvvmLight_Command:EventToCommand x:Name="VideoPivotClicked"
                                                            Command="{Binding VideoPivotClicked,  Mode=OneWay}" PassEventArgsToCommand="True" />
            </Custom:EventTrigger>
        </Custom:Interaction.Triggers>
  

Затем в вашей viewmodel вы добавляете это

       public RelayCommand<SelectionChangedEventArgs> VideoPivotClicked
  {
      get;
      private set;
  }

VideoPivotClicked = new RelayCommand<SelectionChangedEventArgs>(arg =>
                                                       {
                                                           PivotItem pivotItem = arg.AddedItems[0] as PivotItem;
                                                           Pivot pivot = pivotItem.Parent as Pivot;
                                                           Debug.WriteLine(pivot.SelectedIndex);
                                                       }
          );
  

Вы не получите PivotItem, который собираетесь! и не тот, который вы оставляете.

Ответ №3:

Я не использовал MVVM Light напрямую, но вы должны иметь возможность привязать выбранный индекс / элемент к свойству в модели представления. Когда это свойство будет изменено, вы могли бы выполнить свой switch.

Ответ №4:

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

Для вашего конкретного случая в вашем операторе switch просто вызовите общедоступный метод в вашей ViewModel. Как получить ссылку на viewmodel? Вы можете получить это с помощью DataContext представления. Итак, теперь ваши представления могут вызывать общедоступные методы (и свойства) в вашей ViewModel.

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

Ответ №5:

Я получаю индекс для сводного элемента, который я оставляю, а не для сводного элемента, который я собираюсь! .

Используя это:

 <controls:Pivot x:Name="pivMain" Title="{Binding AppName}" >
         <Custom:Interaction.Triggers>
            <Custom:EventTrigger EventName="SelectionChanged">
                    <cmd:EventToCommand Command="{Binding SelectServiceCommand}"          
                    CommandParameter="{Binding ElementName=pivMain, Path=SelectedIndex}"/>
             </Custom:EventTrigger>
        </Custom:Interaction.Triggers>