locked
Ui.Xaml.Control.ListView and determining which indicies are selected, C#

    Question

  • I have a Windows Store app, using a Ui.Xaml.Control.ListView<string>.

    I have some items selected.  I need to know the index of each item that is selected. I just don't see how to get there.

    var indicies = Foo.SelectedItems;  gets you an array of strings that are selected, but not their original indexes.

    There is no Foo.SelectedIndexes,  and there is no Foo.Items[0].IsSelected logical test. 

    So how do you iterate through and see what indexes are selected?

    Thanks.

    p.s. Right now I am using this work around:

               for (int i = 0; i < ItemListView.Items.Count;i++ )
                {
                    if (ItemListView.SelectedItems.Contains(ItemListView.Items[i]))
                    {
                    }
                }
    Which is totally bogus, because you could have duplicate entries and you will get the wrong index.


    • Edited by srihCsrihC Wednesday, September 17, 2014 8:13 PM more info
    Wednesday, September 17, 2014 8:04 PM

Answers

  • Your ListView items are not of type string anymore but of type SimpleModel. So you need to cast it to SimpleModel when calling the IndexOf method:

    listSelectedIndexes.Add(listModels.IndexOf((SimpleModel)selectedItem));
    Just as a side note: The ListView and similar controls do not work properly if you add the same object multiple times. In the original code you tried to add the same string twice, which would have led to problems sooner or later, even if you would not have needed the indices. The new approach is correct: If you want to add the same item multiple times, you must create a "container" class (in this case called SimpleModel). Then you can create multiple containers with the same content and add them to the ListView.
    • Edited by Lukas F Thursday, September 25, 2014 7:19 PM
    • Marked as answer by srihCsrihC Monday, September 29, 2014 7:14 PM
    Thursday, September 25, 2014 7:18 PM

All replies

  • Hi srihCsrihC,

    SelectedIndex does not help? Use Foo.SelectedIndex without "es" should work fine.

    --James


    <THE CONTENT IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED>
    Thanks
    MSDN Community Support

    Please remember to "Mark as Answer" the responses that resolved your issue. It is a common way to recognize those who have helped you, and makes it easier for other visitors to find the resolution later.

    Thursday, September 18, 2014 1:31 AM
    Moderator
  • Hi srihCsrihC,

    Try lambda like this

    var seectedItems = ListViewName.Where(x=> x.IsSeleletd==ture).Select(x=> new {index = x.Index}.ToList();

    thanks,

    Hope that helps
    Please don't forget to up vote answers you like or which help you and mark one(s) which answer your question.

    ---------------------------------------

    M Prabath Maduranga Peiris
    Microsoft Partner  and MSP/MSA
    Blogs : prabathsl.blogspot.com


    • Edited by PrabathSL Thursday, September 18, 2014 2:50 AM
    Thursday, September 18, 2014 2:50 AM
  • Clearly not. If you have more than one selected (it is a ListView after all).

    Then you need a collection of indices.  Not just one.

    Thursday, September 18, 2014 4:34 PM
  • I can't follow that. Really.  Can you break that down into non-lambda code so we can see what it is doing?

    Beginning programmers often have no way to cope with lambdas.

    I don't even see a .Where listed among ListView properties.

    Thursday, September 18, 2014 4:37 PM
  • Hi, srihCsrihC.

    You can't getting selectedIndexes. Use SelectedItems. 
    You can select all indexes of selectedItems from ItemsSource (ListView).

    For ex. 

    var selectedIndexes = new List<int>();
    for(int i = 0; i < SelectedItems.Count; i++)
    {
       var selectedItem = ItemsSource.FirstOrDefault(it=>it == SelectedItems[i]);
       if(selectedItem != null)
       {
          selectedIndexes.Add(i);
       }
    
       // or 
       if(ItemsSource.Contains(SelectedItems[i]))
       {
           selectedIndexes.Add(i);
       }
    }

    Regards, Nikita.

    Thursday, September 18, 2014 5:18 PM
  • Hi srihCsrihC

    You can try below code:

    ListView listView;
    List<string> weeks= new List<string>(){"sunday", "monday", ...};
    listView.ItemSource= weeks;
    List<int> listSelectedIndexes= new List<int>();
    foreach(var selectedItem in listView.SelectedItems)
    {
    listSelectedIndexes.Add(weeks.IndexOf(selectedItem as string));
    }
    
    //listSelectedIndexes is your indexes.


    Pallam Madhukar Windows Phone Developer

    Thursday, September 18, 2014 5:32 PM
  • Thanks, but this doesn't really work.  The reason is that if you have a list with, for example:

    = "sunday","monday","sunday"

    and the user selects both Sunday's, your output list has two items, both with index zero, when what is the case is index 0 and 2.

    This is an important distinction.  ListView is a View, not a Model, so the view is displaying only the Name property string on a much more complex Collection of 'unique' underlying objects. (for instance: sound.wav and sound.aif, same names yet different objects).

    This really looks like a .NET bug with the Extended feature of ListView.  Clearly the interface that results in the collection SelectedItems can test for unique selected, but no other code option can?  That seems like a big problem. 

    Friday, September 19, 2014 1:17 PM
  • Hi 

    In that case. You can just create any Model object like below and make the list. and give the list as itemsource to ListView.

    public class SimpleModel
    {
    public SimpleModel(strine title)
    {
    Title=title;
    }
    public string Title{get; set;}
    public override string ToString()
    {
    return Title;
    }
    }
    
    //then create list
    List<SimpleModel> listModels= new List<SimpleModel>();
    listModel.Add(new SimpleModel("Sunday"));
    listModel.Add(new SimpleModel("Monday"));
    listModel.Add(new SimpleModel("Sunday"));

    Hope this works for you. :)


    Pallam Madhukar Windows Phone Developer

    Saturday, September 20, 2014 5:21 AM
  • using System.Collections.Generic;
    using Windows.UI.Xaml;
    using Windows.UI.Xaml.Controls;
    
    namespace App2
    {
        public class SimpleModel
        {
            public SimpleModel(string title)
            {
                Title = title;
            }
            public string Title { get; set; }
            public override string ToString()
            {
                return Title;
            }
        }
    
        public sealed partial class MainPage : Page
        {
            List<SimpleModel> listModels = new List<SimpleModel>();
    
            public MainPage()
            {
                this.InitializeComponent();
    
                listModels.Add(new SimpleModel("Sunday"));
                listModels.Add(new SimpleModel("Monday"));
                listModels.Add(new SimpleModel("Sunday"));
                listModels.Add(new SimpleModel("Sunday"));
                // lv is a ListView on the page. Select mode set to EXTENDED
                lv.SelectionMode = ListViewSelectionMode.Extended;
                lv.ItemsSource = listModels;
            }
            // Select the sundays and hit a button to see: 0,2,3 as indicies
            private void Button_Click(object sender, RoutedEventArgs e)
            {
                List<int> listSelectedIndexes = new List<int>();
                foreach (var selectedItem in lv.SelectedItems)
                {
                    // ERROR: cannot convert 'string' to SimpleModel
                    listSelectedIndexes.Add(listModels.IndexOf(selectedItem as string));
                }
            }
        }
    }
    

    I'm still getting errors.  Cannot get the index of listModels, based on a string.

    Tuesday, September 23, 2014 3:09 PM
  • Your ListView items are not of type string anymore but of type SimpleModel. So you need to cast it to SimpleModel when calling the IndexOf method:

    listSelectedIndexes.Add(listModels.IndexOf((SimpleModel)selectedItem));
    Just as a side note: The ListView and similar controls do not work properly if you add the same object multiple times. In the original code you tried to add the same string twice, which would have led to problems sooner or later, even if you would not have needed the indices. The new approach is correct: If you want to add the same item multiple times, you must create a "container" class (in this case called SimpleModel). Then you can create multiple containers with the same content and add them to the ListView.
    • Edited by Lukas F Thursday, September 25, 2014 7:19 PM
    • Marked as answer by srihCsrihC Monday, September 29, 2014 7:14 PM
    Thursday, September 25, 2014 7:18 PM