How to use Virtual mode in ListView? - c#

i'm using VirtualMode to fill the columns like
List<ListViewItem> m_lstItem;
private void Form1_Load(object sender, EventArgs e)
{
m_lstItem = Enumerable.Range(0, 100000).Select(X => new ListViewItem(new String[] { X.ToString(), (X + 1).ToString() })).ToList();
listView1.VirtualListSize = m_lstItem.Count;
}
private void listView1_RetrieveVirtualItem(object sender, RetrieveVirtualItemEventArgs e)
{
e.Item = m_lstItem[e.ItemIndex];
}
but i can not access the selected item. while accessing the selected item its throwing an error like Cannot access the selected items collection when the ListView is in virtual mode.
How do i get the selected items from the listView when it is in VirtualMode
Please help me to do this.

From MSDN:
In virtual mode, the Items collection is disabled. Attempting to access it results in an InvalidOperationException. The same is true of the CheckedItems collection and the SelectedItems collection. If you want to retrieve the selected or checked items, use the SelectedIndices and CheckedIndices collections instead.

The Items collection is not available as an iterable collection in Virtual Mode but it is always possible to access a single element using Items(SelectedIndices(0)). I found that it works also using FULLROWSELECT. The problem is referenced on another page of this same site: Cannot access the selected items collection when the ListView is in virtual mode?

For some reason the SelectedIndices were always invalid when I tried to use them, maybe because of using FULLROWSELECT.
The selected item was available however even if the documentation wasn't clear. I found it with the ItemSelectionChanged event handler as e.ItemIndex.
Hope this might be helpful to someone else.

Related

Treeview.Items.Clear() method return null exception (e.NewValue==null) in SelectedItemChanged Event

I am from Iran and I cant speak English very well, sorry.
I made something like OpenFileDialog in WinForms
and work correctly.
After, for better user interface, I tried to make it in WPF.
I use TreeView and other controls for it in both platforms (Winforms and WPF)
in Winforms I could do this correctly usingbelow code:
private void Folder_FileTreeView_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e)
{
Folder_FileTreeView.Nodes.Clear();//this is necessary to clean first page node, after get new folders
if(e.Node.Text=="Desktop")//also this code is necessary to compare node
{
//Do something
}
}
Also in WPF I can get text of Item by below code:
private void Folder_FileTreeView_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
{
if (e.NewValue!=null)
{
StackPanel CustomStackPanel = (StackPanel)((TreeViewItem)e.NewValue).Header;
TextBlock textBlock = (TextBlock)CustomStackPanel.Children[1];
nodetext = textBlock.Text;//this line return text of item for compare
}
Folder_FileTreeView.Items.Clear();
}
If I don't use Folder_FileTreeView.Items.Clear() the above code return folders without clearing first page, but if I do use Folder_FileTreeView.Items.Clear() e.NewValue returns null.
Please help me to use together these codes: Folder_FileTreeView.Items.Clear();(or clear first page) and get text of selecteditem by user without return null
Thanks A lot
e.NewItem will be null if the TreeView used to have an item selected but now does not. When you clear the items, you are removing any selection, this of course changes the selection and raises the SelectedItemChanged event with null as the new selection- since there are no possible items that could be selected.
If you want to replace the items in the list with new items after the user makes a selection, the selected item will be null while that change is happening. You need to do the following:
Handle the SelectedItemChanged event and remember the new selected item in a variable.
For example, if they click on the item for "Desktop" set a variable (e.g. Path) to the path for the user's desktop (e.g. C:\Users\UserName\Desktop).
Clear the list of folders in the TreeView. This will trigger SelectedItemChanged again, but you want to ignore it this time because e.NewItem == null.
Read all the folders in Path and make new items for each of those folders.
The way was found by below code
private void Folder_FileTreeView_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
{
Folder_FileTreeView.SelectedItemChanged -= Folder_FileTreeView_SelectedItemChanged;
if (e.NewValue!=null)
{
StackPanel CustomStackPanel = (StackPanel)((TreeViewItem)e.NewValue).Header;
TextBlock textBlock = (TextBlock)CustomStackPanel.Children[1];
nodetext = textBlock.Text;//this line return text of item for compare
}
Folder_FileTreeView.Items.Clear();
Folder_FileTreeView.SelectedItemChanged += Folder_FileTreeView_SelectedItemChanged;
}
thank very much for every one helped me

C# listview checked box

I am trying to get the index of a listview item that has just being checked and update a database based on the item that was just checked not considering other items that were checked before
I am trying to use the checkbox to indicate a user wants a notification or not, so when a user checks the checkbox, i want to use the index of the item and set notification for that item to true but i can only get all the checkeditems indexes at once.
Any help please.
I was able to call the itemcheck event function but it considers items checked initially as well as items checked by user.
I managed to separate the items checked initially using a boolean function "Item_checked by user"
` private static bool checked_by_user;
private void courseworks_ItemCheck(object sender, ItemCheckEventArgs e)
{
if (checked_by_user == true)
{ //do something
}
else ;//do nothing
}`
Now, I want to be able to take the bar_ref_id of only the line that was just checked, My list view is created from a database as below
foreach (var item2 in CW_query2)//for each CW
{
if (item.Status == true)
{
ListViewItem items = new ListViewItem(new[] {//adds items into list view, per column
item2.Module_Code, item2.Title, item2.Due_Date.ToString("dd/MM/yy"),"Submitted",item.Bar_Ref_ID
});
courseworks.Items.Add(items);
}
else
{
ListViewItem items = new ListViewItem(new[] {//adds items into list view, per column
item2.Module_Code, item2.Title, item2.Due_Date.ToString("dd/MM/yy"),"Not-Submitted",item.Bar_Ref_ID
});
courseworks.Items.Add(items);
}
I hope my added info helps.
Thanks in advance
If you're already getting the subscriptions from the database and setting the Checked property for each item according to the the user's subscription, wouldn't it be easiest to use the checkboxes' CheckedChanged Event? It's hard to tell what your implementation might be, but you should be able to have one function for when the box is unchecked (removing a subscription), and another function for when the box is checked (adding a subscription).
If you are able to provide some code, I might be able to be more specific.
More Specific
In your ItemChecked event, .NET exposes the object sender and ItemCheckEventArgs e as the parameters of the event. Inside that function, you can look at the sender to get the ListViewItem that has been checked/unchecked, and you can look in e to retrieve the index of that item in the ListView (in case you can use the index to easily change data in your database). Here's a brief example I'm going to almost steal straight from Microsoft:
private void ListView1_ItemCheck1(object sender, ItemCheckEventArgs e)
{
ListViewItem item = (ListViewItem)sender
if (e.CurrentValue==CheckState.Unchecked)
{
Unsubscribe(e.Index, currentUserID);
/*You can pass the Index of the ListViewItem that caused the event
to a method that will update your database (I would find it easier
to program a function that takes the current user's ID as a parameter)*/
Unsubscribe(item.Name, currentUserID);
/*OR this might be a better way for you to reference what subscription
should be cancelled (again, in addition to a UserID)*/
}
else if((e.CurrentValue==CheckState.Checked))
{
Subscribe(e.Index, currentUserID);
}
}
private void Unsubscribe(int index, int userID)
{
//unsubscribe the referenced userID from the subscription at index
}
private void Unsubscribe(string subscriptionName, int userID)
{
//unsubscribe the referenced userID from the subscription called subscriptionName
}
I am unable to provide a more specific example for your second bit of code, because I'm not quite certain what it's doing. It looks like you might be doing something more complicated than the code example above can handle, but perhaps the code will assist you.

Can't remove item from ObservableCollection through ContextMenu

I have a program with a class called MyClass and Location. MyClass contains an ObservableCollection of Location items and Location contains a string property called Name. In MainPage.xaml I have a LongListSelector (with a ContextMenu for each item) populated with grids representing a Location.
When I click the 'remove' menu item from the context control, it will usually remove the underlying Location object and update the view. After a few cycles of populating the LongListSelector and removing all its items, some new items that are added can't be removed anymore.
Here's an example of what I mean: The LLS originally contains 2 items. Then I delete those 2 items and add 3 more. However, I can only remove the third one, in this case, but not the first 2.
Here's the ContextMenu MenuItem click event from MainPage.xaml.cs:
private void MenuItem_Click(object sender, RoutedEventArgs e)
{
var selectedItem = (sender as MenuItem).DataContext as Location;
for (int i = 0; i < MyClass.Locations.Count; i++)
{
if (MyClass.Locations[i].Name == selectedItem.Name)
{
MyClass.Locations.Remove(MyClass.Locations[i]);
break;
}
}
}
Prior to using a for loop, I used this LINQ code and still had the same problem:
var toRemove = MyClass.Locations.Where(x => x.Name == selectedItem.Name).SingleOrDefault();
MyClass.Locations.Remove(toRemove);
Any suggestions to fix this problem?
I suggest you to use a ListBox instead of LLS - if you are not using grouping option. It works much better and causes less problems.
By the way I've also encountered some problems with this Control - maybe similar to yours. Weird is also that LLS.UpdateLayout() doesn't work while in ListBox works perfect.

get the clicked item from a IsItemClickEnabled ListView in C# and WinRT

how can I get the clicket elevent from a ListView which has the IsItemClickEnabled enabled?
I know how to get the selected Item/Index but not the clicked item.
ItemClick is working but I can not say s.th. like:
Object selection = listView1.SelectedItem;
EDIT:
I have a ListView and I need to catch the clicked item from this list in the following method:
private void listView1_ItemClick(object sender, ItemClickEventArgs e)
{
...
}
I may be missing something, but doesn't the following work for you?
private void lv_ItemClick_1(object sender, ItemClickEventArgs e)
{
var item = e.ClickedItem as String;
}
Here I assume the items in the list are simple strings, but in general they'll be whatever type you are using in the collection you've bound to the ItemsSource property of the ListView.
I guess you can also try the SelectionChanged event, and get the clicked item as e.AddedItems or MyListView.SelectedItem or MyListView.SelectedItems.

WP7 Tombstoning - cannot set list selected item value from State data

I am setting up tombstoning for a simple WP7 app. I have a list of items, and I want to save the ListBox.SelectedIndex in State memory, and on returning to the page, have that item selected in the list.
When I try the following code, saving the value seems to work (I have confirmed by displaying it in a MessageBox) but the list item is not selected.
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
if (State.ContainsKey("activeResult"))
{
listBox1.SelectedIndex = Convert.ToInt32(State["activeResult"]);
}
base.OnNavigatedTo(e);
}
protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
{
State["activeResult"] = listBox1.SelectedIndex;
base.OnNavigatedFrom(e);
}
The code compiles with no errors - but the listbox item is just never selected.
thanks for your help!
cheers
Will
Wild guess says you're databinding the List after you set the SelectedIndex, and as such it have no effect (unless it's zero).
Solution: Ensure your ViewModel is initialized, and loaded before you set the SelectedIndex, or databind the SelectedIndex property, and set it on your ViewModel, rather than on the UI component.

Categories

Resources