Contents tagged with mvvm
-
Converting from Silverlight To Universal Apps – MVVM, ListView and Commands
Converting a Windows Phone Silverlight app to a Universal WinRT app isn’t straight forward, and it’s hard to Google for answers. I converted one of my not too advanced apps to universal Windows/Phone and here are some of the things I had to do. The quick-list for Xaml changes is here.
I’m using MVVMLight because it makes it so much easier to develop apps. When developing the Silverlight app I used Interation.Triggers and EventTrigger/EventToCommand to fire off commands in my ViewModel from clicked ListBox items. When converting to universal/winrt I ran into problems with referencing the Microsoft.Expression.Interactions assemblies for the Windows and Windows Phone projects so I decided to code up a simple ItemClickCommand instead which uses an attach property on the ListView. Based (more or less a replica) on the code by Marco Minerva, the command-class looks like this:
public static class ItemClickCommand { public static readonly DependencyProperty CommandProperty = DependencyProperty.RegisterAttached("Command", typeof (ICommand), typeof (ItemClickCommand), new PropertyMetadata(null, OnCommandPropertyChanged)); public static void SetCommand(DependencyObject d, ICommand value) { d.SetValue(CommandProperty, value); } public static ICommand GetCommand(DependencyObject d) { return (ICommand) d.GetValue(CommandProperty); } private static void OnCommandPropertyChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs) { var listView = dependencyObject as ListViewBase; if (listView != null) listView.ItemClick += (sender, itemClickEventArgs) => { var viewBase = sender as ListViewBase; var command = GetCommand(viewBase); if (command != null && command.CanExecute(itemClickEventArgs.ClickedItem)) command.Execute(itemClickEventArgs.ClickedItem); }; } }
The command in the ViewModel is set up like this:public class SportsViewModel : ViewModelBase { public ObservableCollection<Sport> Sports { get; set; } public RelayCommand<Sport> SportSelected { get; private set; } public SportsViewModel() { SportSelected = new RelayCommand<Sport>(sport => { if (sport == null) return; //should not happen _navigationService.NavigateTo(typeof(LeaguesView), sport.Id); }); } //and so on... }
And this is how I use this command in the XAML view:<ListView IsItemClickEnabled="True" SelectionMode="None" commands:ItemClickCommand.Command="{Binding SportSelected}" ItemsSource="{Binding Sports}" > <ListView.ItemTemplate> <DataTemplate> <TextBlock Text="{Binding Name}" /> </DataTemplate> </ListView.ItemTemplate> </ListView>
Remember to set the IsItemClickEnabled and SelectionMode properties for your ListView or nothing will happen when you click the items in the list