I have a WP8 DataBound app with an ItemViewModel bound to a LongListSelector.
Quite simply, when the user taps on an item in the list, I need to retrieve the index number of the item selected for future use. (0 is first in the list, 1 is second, etc.)
So, just as this might retrieve a certain property of the selected item:
string whateverProperty = (MyLongListSelector.SelectedItem as ItemViewModel).WhateverProperty;
I need something like this (obviously made up code):
int indexNumber = (MyLongListSelector.SelectedItem as ItemViewModel).GetSelectedIndex();
I think the SelectedIndex property is the thing I need but I can't figure out how retrieve it.
Thank you!
EDIT: SOLVED! The following gets me exactly what I was looking for:
int selectedIndex = App.ViewModel.Items.IndexOf(MainLongListSelector.SelectedItem as ItemViewModel);
I had the same problem. You need to use the ItemSource to retrieve the index. It should match your data template index for index.
int selectedIndex = selector.ItemsSource.IndexOf(selector.SelectedItem as ItemViewModel);
selector references the LongListSelector object sender. Hope this helps!
Related
My listbox is having a grouped list so basically I want to find listbox group item index with item value. Listbox is having item source bind to it and is having DisplayMemberPath and SelectedValuePath set from code behind.
What I have tried yet are as follow:-
int index = istboxName.Items.IndexOf(ListBindToItemSource.particularParameterValue);
Give index=-1 always.
Another solution I tried is:
int index = ListboxName.Items.Groups.IndexOf(ListBindToItemSource.particularParameterValue);
Same result index=-1 always.
You should never need to access the items that way, instead access the item in your bound source and manipulate that. If you want to change anything in the view, like e.g. a Background, bind it on your item and change it at the source.
Here's my problem: I need to make a DataGrid with dynamic comboboxes using the WPF. If the value of a combobox is already used in the previous rows, the next ones, that will be added by the user, shouldn't contain the item already used.
In this image, the ITEM A shouldn't apear on the combobox of the second line.
I don't have ideia how to accomplish this, can anyone show me a light?
OBS: The DataGrid ItemsSource is binded to an ObservableCollection, and the DataGridComboBoxColumn ItemsSource is a List.
Thanks !!!
The ItemsSource of the combo doesn't have to be bound to an ObservableCollection, but it can help depending on exactly how you solve this.
When that cell goes in to edit mode the property the ItemsSource is bound to gets hit - so you can return a new list of items each time the getter is hit. Here is a very basic example to give you an idea:
public List<string> MyItemsSource
{
get
{
var myNewList = MyMasterList.ToList(); //create a (reference) copy of the master list (the items are not copied though, they remain the same in both lists)
if (PropertyA != null)
myNewList.Remove(PropertyA);
return myNewList;
}
}
So what you are creating and returning is a filtered version of your master list of all possible items. LINQ will be of great help to you here.
Alternatively you could keep just one static copy of the master list as an ObservableCollection, and simply remove items from that static copy as they get selected (and add them back in as they get unselected). Which option you choose will depend on how many times the list can be modified due to items being selected and how complicated it is to generate the list. I've used the dynamically generated list many times in the past, it's an option that works well in most cases.
I'm working with a LongListSelector that has a context menu attached to it as part of the ItemTemplate in the XAML. One of my context items is an edit option. In the click event of that option, I want to get the LongListSelector's index of the item being edited (aka the selected item), so that I can use it later. However, I'm having problems getting it to work. I've tried the following two things:
LongListSelector selector = (sender as MenuItem).DataContext as LongListSelector;
int selectedIndex = selector.ItemsSource.IndexOf(selector.SelectedItem);
MessageBox.Show(string.Format("{0}", selectedIndex)); //What's the index?
However, this always returns -1.
I've also tried accessing the list directly instead of through the sender, as below:
int selectedIndex = listTypedNotes.ItemsSource.IndexOf(listTypedNotes.SelectedItem);
MessageBox.Show(string.Format("{0}", selectedIndex)); //What's the index?
This also returns -1.
Any ideas?
I've figured out the answer.
NoteData data = (sender as MenuItem).DataContext as NoteData;
int selectedIndex = App.ViewModel.TypedNote.Items.IndexOf(data);
So, I basically asked my MenuItem to give me the information from the selected item of the LongListSelector, which is a NoteData item. Then, I got the index of that item, to give me the selected index!
I have a listbox that is being filter like this:
var view = CollectionViewSource.GetDefaultView(FilterSource);
view.Filter = FilterCode;
I am running into a problem where the SelectedItem is getting lost when the filter is used with viewmodel code like this:
VM
{
public ObservableCollection<Model> Items{get;set;}
public Model SelectedItem
{
get{return _selectedItem;}
set{_selectedItem = value; NotifyPropertyChanged();}
}
}
When the filter is applied, the SelectedItem is set to null. However, I want to keep that selected item unless the user actually clicks off of it. If the filter is removed, then the selected item should still be selected. The Model does have an IsSelected property, and I have been trying to think of ways to query for the IsSelected property. However, then the view's binding would not work the way I expect....or at least I am going in circles thinking it cannot
My only way of accomplishing a fix here is the following in the SelectionChanged event:
if (e.AddedItems.Count == 0 && e.RemovedItems.Count >= 0)
SpecialtyListBox.SelectedItem = e.RemovedItems[0];
But, this seems really hacky and forces that there must always be an item selected once an initial one is selected. In this case, that might work, but I would still like to see if anybody has a better solution?
I had a similar problem, where the listboxes were shown as tabbed views. I solved the problem by creating a Converter to produce a Boolean flag for "isActive" and assigning it to CollectionViewSource.IsLiveFilteringRequested. This prevented the non-active list boxes from updating the selected item.
You can fix this by creating a filter that always adds the current selected item to the filtered items. If this cannot be done directly, just hold the selected item in a separate variable.
I'm trying to sort the items in a ListBox. However, upon doing so the Item Value gets set to the Item Text. Any help would be appreciated.
lbxCustomers.DataSource = lbxCustomers.Items.Cast<ListItem>().Reverse().ToList();
lbxCustomers.DataBind();
May be first you should store the list in generic collection and then sort it. Something like this:
List<ListItem> list = new List<ListItem>(lbxCustomers.Items.Cast<ListItem>());
list = list.OrderBy(li => li.Text).ToList<ListItem>();
lbxCustomers.Items.Clear();
lbxCustomers.Items.AddRange(list.ToArray<ListItem>());
Try resetting the DisplayMember and ValueMember properties of the Listbox after setting the DataSource. A lot of times if a control is already bound and you set the DataSource again, then it drops the DisplayMember/ValueMember properties.
Try sorting the list separately.
Point the Text value and Data value in the next step.
Databind the control.