Attention: We are retiring the ASP.NET Community Blogs. Learn more >

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 Smile