none
How to pre-select multiple listview/gridview items ?

    Question

  • Hi, in my app there is gridview of my custom class. I am using custom data template and values are bound from SQLite. Now when user launch the app, the certain items (NOT SINGLE) should be pre-selected in gridview/listview. Gridview/listview allows multiple selection. How can I achieve this with SelectedItem property ? 

    • Edited by Xyroid Wednesday, October 03, 2012 11:25 AM
    Wednesday, October 03, 2012 10:57 AM

Answers

  • Sol 3: example with SQLite:

    <Page
        x:Class="App2.MainPage"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:App2"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d">
    
        <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
            <ListView x:Name="listView" SelectionMode="Multiple">
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <StackPanel Orientation="Horizontal">
                            <TextBox Text="{Binding ID}" Margin="0,0,5,0"/>
                            <TextBox Text="{Binding Title}"/>
                        </StackPanel>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>
        </Grid>
    </Page>

    -

    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.Diagnostics;
    using System.IO;
    using System.Linq;
    using Windows.Foundation;
    using Windows.Foundation.Collections;
    using Windows.UI.Xaml;
    using Windows.UI.Xaml.Controls;
    using Windows.UI.Xaml.Controls.Primitives;
    using Windows.UI.Xaml.Data;
    using Windows.UI.Xaml.Input;
    using Windows.UI.Xaml.Media;
    using Windows.UI.Xaml.Navigation;
    
    namespace App2
    {
        public sealed partial class MainPage : Page
        {
            public MainPage()
            {
                this.InitializeComponent();
                LoadData();
            }
            protected override void OnNavigatedTo(NavigationEventArgs e)
            {
            }
            ObservableCollection<KiwiItem> sourceColl;
            IList<KiwiItem> selectionList;
            public void LoadData()
            {
                var dbPath = Path.Combine(Windows.Storage.ApplicationData.Current.LocalFolder.Path, "db.sqlite");
                
                // Exec (1)
                using (var db = new SQLite.SQLiteConnection(dbPath))
                {
                    db.DropTable<KiwiItem>();
                    db.CreateTable<KiwiItem>();
                    db.RunInTransaction(() =>
                    {
                        db.Insert(new KiwiItem() { ID = 1, Title = "MyTitle1" });
                        db.Insert(new KiwiItem() { ID = 2, Title = "MyTitle2" });
                        db.Insert(new KiwiItem() { ID = 3, Title = "MyTitle3" });
                        db.Insert(new KiwiItem() { ID = 4, Title = "MyTitle4" });
                    });
                    this.sourceColl = new ObservableCollection<KiwiItem>();
                    this.selectionList = new List<KiwiItem>();
                    // Query the db. In practice, fill the sourceColl according to your business scenario
                    foreach (KiwiItem item in db.Table<KiwiItem>())
                    {
                        this.sourceColl.Add(item);
                        if (item.ID == 2 || item.ID == 4)
                            this.selectionList.Add(item);
                    }
                }
    
                // Exec (2)
                this.listView.ItemsSource = this.sourceColl;
                foreach (KiwiItem item in this.selectionList)
                    this.listView.SelectedItems.Add(item);
            }
        }
        public class KiwiItem
        {
            [SQLite.AutoIncrement, SQLite.PrimaryKey]
            public int ID { get; set; }
            public string Title { get; set; }
        }
    
    }



    Tuesday, October 16, 2012 6:36 AM

All replies

  • i have the same problem.

    Set a default selectedItem in GridView


    Sara Silva

    Wednesday, October 03, 2012 11:02 AM
  • Hello,

    GridView has a property called SelectedItems, but unfortunately it is read-only and not a dependency property. Therefore you cannot bind to it in the xaml code.

    To work around this, you could either work with events (to notify the code-behind of the view of any changes made to the selection) or you could add a dependency property to the code-behind of your view, bind it to the view model and then "transfer" the selection in the code behind to the GridView.

    Cheers


    Helge Mahrt - Microsoft Developer Support Engineer - If my reply answers your question, please mark this post as answered.

    Wednesday, October 03, 2012 12:32 PM
  • I found a way. You can use the SelectedItems property and call SelectedItems.Add() or SelectedItems.Remove() to add/remove items from selection. Check this also. Let me know if that worked for you or not.
    Friday, October 05, 2012 9:08 AM
  •  SelectedItems.Add() doesn't work, kindly check my conversation with Filip Skakun on StackOverflow. I request others pro members to help me with this problem. Thanks
    Wednesday, October 10, 2012 11:04 AM
  • Here I am posting the basic codes. While debugging the selecteditems has values but it doesn't show them selected.

    XAML

    <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
        <ListView Name="MyListView" SelectionMode="Multiple" Width="100" HorizontalAlignment="Center" VerticalAlignment="Center" />
    </Grid>

    C#

    protected override void OnNavigatedTo(NavigationEventArgs e)
    {
        List<int> MyIntegers = new List<int>();
        List<int> MySelectedIntegers = new List<int>();
        
        for (int i = 1; i < 11; i++)
        {
            MyIntegers.Add(i);
        }
    
        MySelectedIntegers.Add(1);
        MySelectedIntegers.Add(2);
        MySelectedIntegers.Add(9);
    
        foreach (int item in MySelectedIntegers)
        {
            MyListView.SelectedItems.Add(item);
        }
    
        MyListView.ItemsSource = MyIntegers;
    }
    Monday, October 15, 2012 5:26 AM
  • Sol 1: example with integer, string, etc.:

    <Page
        x:Class="App14.MainPage"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:App14"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d">
    
        <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
            <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
                <ListView Name="MyListView" SelectionMode="Multiple" Width="100" HorizontalAlignment="Center" VerticalAlignment="Center" />
            </Grid>
        </Grid>
    </Page>

    -

    using System.Collections.Generic;
    using Windows.UI.Xaml.Controls;
    using Windows.UI.Xaml.Navigation;
    
    namespace App14
    {
        public sealed partial class MainPage : Page
        {
            public MainPage()
            {
                this.InitializeComponent();
            }
            protected override void OnNavigatedTo(NavigationEventArgs e)
            {
                // Note : it is recommended to use 'ObservableCollection<int>
                List<int> MyIntegers = new List<int>();
                List<int> MySelectedIntegers = new List<int>();
                // Move here so that MyListView 'recognizes' selected items as belonging to the collection
                MyListView.ItemsSource = MyIntegers;
                for (int i = 1; i < 11; i++)
                {
                    MyIntegers.Add(i);
                }
                // Selection
                MySelectedIntegers.Add(1);
                MySelectedIntegers.Add(2);
                MySelectedIntegers.Add(9);
                foreach (int item in MySelectedIntegers)
                {
                    MyListView.SelectedItems.Add(item);
                }
            }
        }
    }



    Monday, October 15, 2012 6:02 AM
  • Thanks ForInfo, but when I tried with custom class instead of integer it does not work.

    <ListView Name="MyListView" SelectionMode="Multiple" HorizontalAlignment="Center" VerticalAlignment="Center">
        <ListView.ItemTemplate>
            <DataTemplate>
                <StackPanel>
                    <TextBlock Text="{Binding ID}" FontSize="20"/>
                    <TextBlock Text="{Binding Date}" FontSize="20"/>
                </StackPanel>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
    

    protected override void OnNavigatedTo(NavigationEventArgs e)
    {
        ObservableCollection<timedate> MyIntegers = new ObservableCollection<timedate>();
        ObservableCollection<timedate> MySelectedIntegers = new ObservableCollection<timedate>();
    
        MyListView.ItemsSource = MyIntegers;
    
        MyIntegers.Add(new timedate { Date = DateTime.Now, ID = 1 });
        MyIntegers.Add(new timedate { Date = DateTime.Now, ID = 2 });
        MyIntegers.Add(new timedate { Date = DateTime.Now, ID = 3 });
        MyIntegers.Add(new timedate { Date = DateTime.Now, ID = 4 });
        MyIntegers.Add(new timedate { Date = DateTime.Now, ID = 5 });
    
        MySelectedIntegers.Add(new timedate { Date = DateTime.Now, ID = 5 });
        MySelectedIntegers.Add(new timedate { Date = DateTime.Now, ID = 3 });
        MySelectedIntegers.Add(new timedate { Date = DateTime.Now, ID = 1 });
    
        foreach (var item in MySelectedIntegers)
        {
            MyListView.SelectedItems.Add(item);
        }
    }
    

    public class timedate
    {
        public int ID { get; set; }
        public DateTime Date { get; set; }
    }
    

    • Edited by Xyroid Monday, October 15, 2012 9:42 AM
    Monday, October 15, 2012 8:50 AM
  • Sol 2: example with object references:

    Please find the solution for non-primitive types. These are - unlike integers, strings, etc. - equal by 'reference' and not by 'value' [to simplify]

    <Page
        x:Class="App15.MainPage"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:App15"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d">
    
        <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
            <ListView Name="MyListView" SelectionMode="Multiple" HorizontalAlignment="Center" VerticalAlignment="Center">
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <StackPanel>
                            <TextBlock Text="{Binding ID}" FontSize="20"/>
                            <TextBlock Text="{Binding Date}" FontSize="20"/>
                        </StackPanel>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>
        </Grid>
    </Page>

    -

    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using Windows.UI.Xaml.Controls;
    using Windows.UI.Xaml.Navigation;
    
    namespace App15
    {
        public sealed partial class MainPage : Page
        {
            public MainPage()
            {
                this.InitializeComponent();
            }
            protected override void OnNavigatedTo(NavigationEventArgs e)
            {
                // Step 1: initialize collections
                // ObservableCollection<...> for ItemsSource
                ObservableCollection<timedate> MyIntegers = new ObservableCollection<timedate>();
                // IList<...> for SelectedItems
                IList<timedate> MySelectedIntegers = new List<timedate>();
                timedate td; // use this variable to store each of the successive references
    
                // Step 2: populate the MyIntegers & SelectedItems collections
                {
                    td = new timedate { Date = DateTime.Now, ID = 1 };
                    MyIntegers.Add(td); MySelectedIntegers.Add(td);
                    // ...
                    td =new timedate { Date = DateTime.Now, ID = 2 };
                    MyIntegers.Add(td);
                    // ...
                    td = new timedate { Date = DateTime.Now, ID = 3 };
                    MyIntegers.Add(td); MySelectedIntegers.Add(td);
                    // ...
                    td = new timedate { Date = DateTime.Now, ID = 4 };
                    MyIntegers.Add(td);
                    // ...
                    td = new timedate { Date = DateTime.Now, ID = 5 };
                    MyIntegers.Add(td); MySelectedIntegers.Add(td);
                    // Incorrect: This creates a new instance of timedate; 
                    // hence the ObsColl<...> timedate instance will not be retrieved [by reference]
                    // MySelectedIntegers.Add(new timedate { Date = DateTime.Now, ID = 5 });
                    // MySelectedIntegers.Add(new timedate { Date = DateTime.Now, ID = 3 });
                    // MySelectedIntegers.Add(new timedate { Date = DateTime.Now, ID = 1 });
                    // Correct: This fetches the existing instance of timedate out of the ObservableCollection<...> by refering to it
                }
    
                // Step 3: set both collections
                {
                    MyListView.ItemsSource = MyIntegers;
                    foreach (var item in MySelectedIntegers)
                        MyListView.SelectedItems.Add(item);
                }
            }
            public class timedate
            {
                public int ID { get; set; }
                public DateTime Date { get; set; }
            }
        }
    }




    Monday, October 15, 2012 1:34 PM
  • OK, I see. The above solution works if and only if I have values (index) explicitly. What to do if the list of the values which should be preselected, comes from SQLite database ?

    Monday, October 15, 2012 1:54 PM
  • So, the example has been adapted to not use indexed access; but rather 3 successive logical steps.
    Monday, October 15, 2012 2:19 PM
  • I tried this scenario, not working.

    string dbpath = Path.Combine(Windows.Storage.ApplicationData.Current.LocalFolder.Path, "db.db"); using (var db = new SQLite.SQLiteConnection(dbpath)) { MyListView.ItemsSource = db.Table<timedate>(); ObservableCollection<timedate> MySelected = new ObservableCollection<timedate>(); MySelected.Add(new timedate { Date = DateTime.Now, ID = 2 }); //MySelected is the collection for just comparison MySelected.Add(new timedate { Date = DateTime.Now, ID = 1 }); //this is not added in MyListView.SelectedItems foreach (timedate item in MyListView.Items) { foreach (timedate itemSelected in MySelected) { if (item.ID == itemSelected.ID) // just comparing IDs and adding the existing instance from MyListView's items { MyListView.SelectedItems.Add(item); } } } }

    foreach (timedate item in MyListView.SelectedItems)
    {
        System.Diagnostics.Debug.WriteLine(item.Date.ToString() + " : " + item.ID); //while debugging, output window shows the selected items
    }



    • Edited by Xyroid Tuesday, October 16, 2012 6:28 AM
    Tuesday, October 16, 2012 5:04 AM
  • Sol 3: example with SQLite:

    <Page
        x:Class="App2.MainPage"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:App2"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d">
    
        <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
            <ListView x:Name="listView" SelectionMode="Multiple">
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <StackPanel Orientation="Horizontal">
                            <TextBox Text="{Binding ID}" Margin="0,0,5,0"/>
                            <TextBox Text="{Binding Title}"/>
                        </StackPanel>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>
        </Grid>
    </Page>

    -

    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.Diagnostics;
    using System.IO;
    using System.Linq;
    using Windows.Foundation;
    using Windows.Foundation.Collections;
    using Windows.UI.Xaml;
    using Windows.UI.Xaml.Controls;
    using Windows.UI.Xaml.Controls.Primitives;
    using Windows.UI.Xaml.Data;
    using Windows.UI.Xaml.Input;
    using Windows.UI.Xaml.Media;
    using Windows.UI.Xaml.Navigation;
    
    namespace App2
    {
        public sealed partial class MainPage : Page
        {
            public MainPage()
            {
                this.InitializeComponent();
                LoadData();
            }
            protected override void OnNavigatedTo(NavigationEventArgs e)
            {
            }
            ObservableCollection<KiwiItem> sourceColl;
            IList<KiwiItem> selectionList;
            public void LoadData()
            {
                var dbPath = Path.Combine(Windows.Storage.ApplicationData.Current.LocalFolder.Path, "db.sqlite");
                
                // Exec (1)
                using (var db = new SQLite.SQLiteConnection(dbPath))
                {
                    db.DropTable<KiwiItem>();
                    db.CreateTable<KiwiItem>();
                    db.RunInTransaction(() =>
                    {
                        db.Insert(new KiwiItem() { ID = 1, Title = "MyTitle1" });
                        db.Insert(new KiwiItem() { ID = 2, Title = "MyTitle2" });
                        db.Insert(new KiwiItem() { ID = 3, Title = "MyTitle3" });
                        db.Insert(new KiwiItem() { ID = 4, Title = "MyTitle4" });
                    });
                    this.sourceColl = new ObservableCollection<KiwiItem>();
                    this.selectionList = new List<KiwiItem>();
                    // Query the db. In practice, fill the sourceColl according to your business scenario
                    foreach (KiwiItem item in db.Table<KiwiItem>())
                    {
                        this.sourceColl.Add(item);
                        if (item.ID == 2 || item.ID == 4)
                            this.selectionList.Add(item);
                    }
                }
    
                // Exec (2)
                this.listView.ItemsSource = this.sourceColl;
                foreach (KiwiItem item in this.selectionList)
                    this.listView.SelectedItems.Add(item);
            }
        }
        public class KiwiItem
        {
            [SQLite.AutoIncrement, SQLite.PrimaryKey]
            public int ID { get; set; }
            public string Title { get; set; }
        }
    
    }



    Tuesday, October 16, 2012 6:36 AM
  • Phew, finally worked. Thank you so much ForInfo. Can you tell why "MyListView.ItemsSource = db.Table<timedate>()" is not working ?
    Tuesday, October 16, 2012 7:09 AM