locked
Iterating selected items in Windows App Store Gridview RRS feed

  • Question

  • I know this is a long one, but please bear with me.

    I have created a windows app store program very similar to Laurent Bugnion's "MyFriends" program in the MVVM light samples using the MVVM light framework.

    In his program he uses the SelectedItem property of the gridview to keep track of which item is the selected item.

    The problem is, I give the user the ability to select multiple items on the GridView and then operate on them using a button on the App Bar. For this SelectedItem will not work.

    Does anyone know how to make this work with a multiselect GridView? I have tried the IsSelected property of the GridViewItem based on some articles on WPF, but this doesn't seem to work. The SelectedTimesheets getter always come back empty when called. Here is what I have so far:

    MainPage.xaml (bound to a MainViewModel with a child TimesheetViewModel observable collection):

        <GridView 
            x:Name="itemGridView"
            IsItemClickEnabled="True"
            ItemsSource="{Binding Timesheets}"
            ItemTemplate="{StaticResource TimesheetTemplate}"
    
            Margin="10"
            Grid.Column="0"
            SelectionMode="Multiple"
            helpers:ItemClickCommand.Command="{Binding NavigateTimesheetCommand}" RenderTransformOrigin="0.738,0.55"  >
            <GridView.ItemContainerStyle>
                <Style TargetType="GridViewItem">
                    <Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}"/>
                </Style>
            </GridView.ItemContainerStyle>
        </GridView>

    MainViewModel (cut down from full code):

        public class MainViewModel : ViewModelBase
        {
            private readonly IDataService _dataService;
            private readonly INavigationService _navigationService;
            /// <summary>
            /// Initializes a new instance of the MainViewModel class.
            /// </summary>
            public MainViewModel(IDataService dataService, INavigationService navigationService)
            {
                _dataService = dataService;
                _navigationService = navigationService;
                Timesheets = new ObservableCollection<TimesheetViewModel>();
                ExecuteRefreshCommand();
            }
            public ObservableCollection<TimesheetViewModel> Timesheets
            {
                get;
                private set;
            }
            public IEnumerable<TimesheetViewModel> SelectedTimesheets
            {
                get { return Timesheets.Where(o => o.IsSelected); }
            }
            private async void ExecuteRefreshCommand()
            {
                var timesheets = await _dataService.GetTimesheets("domain\\user");
                if (timesheets != null)
                {
                    Timesheets.Clear();
                    foreach (var timesheet in timesheets)
                    {
                        Timesheets.Add(new TimesheetViewModel(timesheet));
                    }
                }
            }
        }

    TimesheetViewModel:

        public class TimesheetViewModel: ViewModelBase
        {
            public bool IsSelected { get; set; }
            public Timesheet Model
            {
                get;
                private set;
            }
            public TimesheetViewModel(Timesheet model)
            {
                Model = model;
            }
        }

    If I set the IsSelected property manually, the SelectedTimesheets lambda works, so the problem is somewhere in the binding of the XAML to the IsSelected property.

    Any help would be appreciated.



    • Edited by ZSico Wednesday, August 21, 2013 2:13 PM
    Wednesday, August 21, 2013 2:09 PM

Answers

  • Ahh, gotcha.  I did not pay attention to the binding you were using in the style setter. This is a known limitation in the XAML platform, you cannot define a binding in the style setter like that.

    Looks like you are already familiar with the attached command behaviors

        helpers:ItemClickCommand.Command="{Binding NavigateTimesheetCommand}"

    You could do something similar to how you handle the ItemClick event for the GridView.SectionChanged event.  If you had a SelectionChangedCommand you could populate the collection of selected Timesheets with the current selected items.

    I have not had time to try this out, but let me know if it works for you.

    Wednesday, August 21, 2013 5:27 PM

All replies

  • Will the GridView.SelectedItems property work for you?  This will return you a list of all the selected items.

    Wednesday, August 21, 2013 4:16 PM
  • Thanks Matt. That's great for code-behind but how would you apply that to the mvvm pattern?
    Wednesday, August 21, 2013 4:20 PM
  • Ahh, gotcha.  I did not pay attention to the binding you were using in the style setter. This is a known limitation in the XAML platform, you cannot define a binding in the style setter like that.

    Looks like you are already familiar with the attached command behaviors

        helpers:ItemClickCommand.Command="{Binding NavigateTimesheetCommand}"

    You could do something similar to how you handle the ItemClick event for the GridView.SectionChanged event.  If you had a SelectionChangedCommand you could populate the collection of selected Timesheets with the current selected items.

    I have not had time to try this out, but let me know if it works for you.

    Wednesday, August 21, 2013 5:27 PM
  • Thanks for the heads up Matt, I'll give it a go and see if I can get it to work. So I presume a lot of the Silverlight and WPF tricks need reworking for WinRT?
    Wednesday, August 21, 2013 5:40 PM
  • Just posted my own answer on Stack Overflow

    http://stackoverflow.com/questions/18359366/iterating-selected-items-in-windows-app-store-gridview/18386228#18386228

    Thanks for the suggestion Matt, SelectionChangedCommand seems to work a treat if you make it a DependancyProperty

    Thursday, August 22, 2013 4:43 PM