Get LongListSelector's selected index through context menu - c#

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!

Related

How can i find item in wpf listbox having grouped list bind to it?

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.

Keep SelectedItem during filter of CollectionViewSource

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.

Getting the SelectedIndex of a LongListSelector Item

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!

Double-Clicking Item in ListView

So I added a list view, and I am displaying 3 columns of strings in each. I also have the full row select on. I want to be able to double click on one of the rows, and have it return the string in the 3rd column. I've tried to look everywhere for a solution to this, but so far nothing comes up.
My code so far is:
private void listView_MouseDoubleClick(object sender, MouseEventArgs e)
{
MessageBox.Show(songList.SelectedItems[2].ToString());
}
Yet it returns an error saying "InvalidArgument=Value of '2' is not valid for 'index'.
Parameter name: index"
You could try:
if (songList.SelectedItems.Count > 0)
{
ListViewItem item = songList.SelectedItems[0];
string s_you_want = item.SubItems[1].Text;
}
Taken a ListViewItem, you can take columns values using SubItems[] property.
I think that you hould bound not your listView to doubleClick event, but listViewItem. sender will have DataContext, from which you can get your third column.
How do you fill the ListView? Wihtout knowing this, it's difficult to help. May be you could try this:
Set a breakpoint in this line:
MessageBox.Show(songList.SelectedItems[2].ToString());
As soon as the debugger hits the breakpoint you could select songList and hit Shift-F9.
Now you can explore the songList and check yourself how to get the string of the third column.
SelectedItems returns a SelectedListViewItemCollection and with the indexer you are accessing elements in this collection, i.e. ListViewItems, not the columns. this means that if you have a single row selected the collection contains only one item, and trying to access the third one gives you the error.
Try (edit according to Marco's comment):
songList.SelectedItems[0].SubItems[1].Text

Listbox item stay focused after selection

I don't know if the title express what I want. I have a ListBox in WPF where I generate many elements. When I click on a element while still generating I want my selected item to not move down the list, so I cannot see it anymore, I want to stay in the exact position where I click on it.
If this is possible, can someone point some ideas on how to do it in C#?
Thanks.
Assuming that this is even a good idea and that you are using winforms
Step 1:
Determine the index of the selected item in the source.
Step 2:
When your adding items to the ListBox split the ListBox at the index where the item previously was insert the item at that point, then add on the remainder of the items, while making sure that you've removed the item if it is now elsewhere in the list.
Code:
//Let's assume that you know how to get the position of the item when it is clicked and save the
//item to a variable called OriginalItem
public void PutTheItemInTheSameSpot()
{
var listboxitems = (List<Integer>)YourListBox.DataSource;
var originalClikedItem = OriginalItem;
var topPart = new List<Integer>();
for (i = 0; i < itemPosition; i++)
{
topPart.Add(listboxItems[i]);
}
topPart.Add(originalClickedItem);
var bottomPart = listboxitems.Remove(toppart);
YourListBox.DataSource = toppart.AddRange(bottomPart);
}
Saw your edit about it being WPF
The could should work in idea.
Just a thought: you could try having your view respond to an event whenever an item is added to your ListBox. In the event handler, you could force the selected item to scroll into view presumably keeping it in the current "viewable" position:
listBox.ScrollIntoView(listBox.SelectedItem);
I've never tried this before so it may or may not produce the desired affect?

Categories

Resources