How to select item from listview in selectedindexchanged event? - c#

private void listView1_SelectedIndexChanged(object sender, EventArgs e)
{
img1 = Image.FromFile(listView1.SelectedItems[0].Text);
pictureBox1.Image = img1;
}
I have 10 items in the listView.
If I'm using it like it is now with SelectedItems[0].Text, when I select any item, the first time it's working fine, but then when I'm selecting another item, it's throwing this error :
System.ArgumentOutOfRangeException: 'InvalidArgument=Value of '0' is not valid for 'index'.
Parameter name: index'

When the event is raised, the details of the item are passed into the event, via 'e'. The type of e will be a ListViewItem, therefore you can use e.Item.Text to access the text of the selected item.
The reason you may be seeing the exception is because I suspect as the selected index changes, it may be unselecting the selected item before it selects the new one, therefore, there isn't an item at Index 0 in this case. You could get around this by wrapping your existing code in an "IF" check like so:
if (listView1.SelectedItems[0] is not null)
{
//DO PROCESSING HERE
}

Related

How to clear listbox selection if I click empty field of listbox?

I have a simple Windows Form which contains a list box called lstVersenyzok. I have a lstVersenyzok_SelectedIndexChanged function. How can I clear the selection of the list box when I click the empty field of the list box? I tried, but it does not work if I check the condition lstVersenyzok.SelectedIndex == -1.
You can use MouseClick event and get the selected index by the IndexFromPoint method.
Check if the index is -1, then call the lstVersenyzok.ClearSelected() to clear the selection.
private void lstVersenyzok_MouseClick(object sender, MouseEventArgs e)
{
int index = this.lstVersenyzok.IndexFromPoint(e.Location);
if(index == -1)
{
lstVersenyzok.ClearSelected();
}
}
Hope this help !!

Error when selecting second item from ListView C#

I have a list view with the multiselect property set to false. When the user clicks on it, I take the NAME property of the list view item and convert it to a decimal then feed that to a method that loads the correct record.
The code below works perfectly when I select one item regardless of how many items are in the list and regardless of which item I select.
private void ListInstruments_SelectedIndexChanged(object sender, EventArgs e)
{
ListViewItem selection = listInstruments.SelectedItems[0];
if (selection != null)
{
string strSelection = selection.Name;
SelectedInstrumentID = Convert.ToDecimal(strSelection);
LoadSelectedInstrument();
}
}
When I make a second selection (not multi-select, but a different selection from the listbox) I get an error referencing listInstruments.SelectedItems[0].
System.ArgumentOutOfRangeException Message=InvalidArgument=Value of
'0' is not valid for 'index'. Parameter name: index
Source=System.Windows.Forms
Any help would be appreciated.
It's possible, that no items are selected, and thus list.SelectedItems is empty; you are tring to get 0th item from the empty collection and thus have the exception thrown. The quick patch is
// instead of original
// ListViewItem selection = listInstruments.SelectedItems[0];
ListViewItem selection = list.SelectedItems.Count > 0
? listInstruments.SelectedItems[0] // the collection has at least one item
: null; // if the collection is empty
Or we can check if we have a selection and return when there's none
private void ListInstruments_SelectedIndexChanged(object sender, EventArgs e)
{
if (list.SelectedItems.Count <= 0)
return;
listViewItem selection = listInstruments.SelectedItems[0];
string strSelection = selection.Name;
SelectedInstrumentID = Convert.ToDecimal(strSelection);
LoadSelectedInstrument();
}

Which Item is user focused in listview xamarin forms

I am a student learning xamarin forms, I am trying to create a basic chat app in this I want to know how to get position of current item in listview that's user watching. When a new message received i want to know if user is at bottom or not if at bottom focus the new and if not at the bottom then just add not by adding focus to it.
you get the selected item from the Xamarin.Forms.ListView.SelectedItem property of your ListView.
If your ListView.ItemSource is of a type that allows using IndexOf you can now do something like
int position = (yourlistview.ItemSource as ObservableCollection<your type>).IndexOf(yourlistview.SelectedItem)
Update:
ok I think i understood what you want.
In most cases more than one item is currently shown when using a listview. So their exists not a single index
but i think you just want to know if the last item of the list is visible/the user has scrolled to the end?
If so ListView has an ItemAppearing event. I use it for example to load more data from an websource if the user scrolled through the first 100 items.
You could do something like this
listview.ItemAppearing += listviewItemAppearing;
listview.ItemDisappearing += listviewItemDisappearing;
bool m_scrolledToEnd;
private void listviewItemDisappearing(object sender, ItemVisibilityEventArgs e)
{
if(e.Item == yourlastiem)
m_scrolledToEnd = false;
}
private void listviewItemAppearing(object sender, ItemVisibilityEventArgs e)
{
if(e.Item == yourlastiem)
m_scrolledToEnd = true;
}
if you realy need to know if a specific index is shown you could create a List<int> m_idxlist;
and in the appearing event add the index of the item to the list
and in the disappearing event remove the index of the item from the list.
Then you will have a list where all indexes of the items currently shown are stored.
From the Documentation
ListView supports selection of one item at a time. Selection is on by
default. When a user taps an item, two events are fired: ItemTapped
and ItemSelected. Note that tapping the same item twice will not fire
multiple ItemSelected events, but will fire multiple ItemTapped
events. Also note that ItemSelected will be called if an item is
deselected.
To detect selecting an item, you can add a method, onSelection:
void OnSelection (object sender, SelectedItemChangedEventArgs e)
{
if (e.SelectedItem == null) {
return; //ItemSelected is called on deselection, which results in SelectedItem being set to null
}
DisplayAlert ("Item Selected", e.SelectedItem.ToString (), "Ok");
//((ListView)sender).SelectedItem = null; //uncomment line if you want to disable the visual selection state.
}
To disable selection just set the selectedItem to null:
SelectionDemoList.ItemSelected += (sender, e) => {
((ListView)sender).SelectedItem = null;
};

Cannot perform runtime binding on a null reference when using type dynamic

I have a listview and this listview will be updated when a message is coming in.
The code below is about how I get the selected row's value.
private void CallTabLv_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
string callDetailValue = "";
dynamic selectedCallDetail;
//When a row of call detail is selected, return the selected row's value only
if (LineBtn1.IsChecked == true)
{
selectedCallDetail = CallTabLv1.SelectedItem;
callDetailValue = selectedCallDetail.Value;
}
if (LineBtn2.IsChecked == true)
{
selectedCallDetail = CallTabLv2.SelectedItem;
callDetailValue = selectedCallDetail.Value;
}
if (string.IsNullOrEmpty(callDetailValue))
callDetailValue = string.Empty;
Clipboard.Clear();
Clipboard.SetText(callDetailValue);
}
It worked fine for first coming message and I could get the selected row's value. The problem is when second message came in, my application stopped and returned "Cannot perform runtime binding on a null reference".
By the way, to return single selected row' value, which one should be used: CallTabLv1.SelectedItem or CallTabLv1.SelectedItems[0]? As I tried, if the latter is used, it will return "ArgumentOutOfRange Exception" when second message is coming in.
Please help.
Update:
When the message is coming in, I update the listview by clearing the whole listview and then print it line by line. I'm not sure if it is caused by the way I update the listview.
So this is probably happening because you are clearing the collection in which you have now changed the selected item. Since the item can be null at that time the dynamic object will be unable to access the property "Value"
You are checking if a checkbox is checked which is not necessarily a condition of if the selected item will exist. I would suggest your code be updated as such.
private void CallTabLv_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
string callDetailValue = "";
dynamic selectedCallDetail;
//When a row of call detail is selected, return the selected row's value only
if (LineBtn1.IsChecked == true)
{
selectedCallDetail = CallTabLv1.SelectedItem;
}
if (LineBtn2.IsChecked == true)
{
selectedCallDetail = CallTabLv2.SelectedItem;
}
// I think the 'invalid' casting is happening with the "selectedCallDetail.Value" as when you clear a listbox it is no longer selected.
callDetailValue = (selectedCallDetail != null) ? selectedCallDetail.Value : string.Empty;
Clipboard.Clear();
Clipboard.SetText(callDetailValue);
}
You should be using the SelectedItem as the SelectedItems collection may be null or empty, If you only ever want one result this is usually the best. also make sure your ListBox only allows for a single item to be selected so that the user cannot crash your code by selecting multiple items using SHIFT or CTRL click

How to move the elements of list box up and down after displaying their properties?

I created a code wherein when i select an item in a list box, the info about the item gets displayed in a text box. I also have move up and down buttons to move the contents of the list up and down and delete button to delete the selected item. Now when i click on the item the info is getting displayed in the text box but if i click on move up, down or delete button for the same item then exception is thrown Object reference not set to an instance of an object. The line that throws this exception is when i am creating a new object of ClassName in the code below:
private void lb_SelectedIndexChanged(object sender, EventArgs e)
{
m_Txt.Clear();
ClassName fileInfo = new ClassName(m_lbOPFfiles.SelectedItem.ToString());
m_Txt.Multiline = true;
m_Txt.Text = fileInfo.title + Environment.NewLine + fileInfo.ID + Environment.NewLine + fileInfo.time;
}
the code for move up button is:
private void m_btnUP_Click(object sender, EventArgs e)
{
if (m_lbOPFfiles.SelectedIndex != 0 && m_lbOPFfiles.SelectedIndex != -1)
{
// m_lbOPFfiles.SelectedItem.
object item = m_lbOPFfiles.SelectedItem;
int index = m_lbOPFfiles.SelectedIndex;
m_lbOPFfiles.Items.RemoveAt(index);
m_lbOPFfiles.Items.Insert(index - 1, item);
}
}
Please tell what possibly could be the problem and the solution for it.
SelectedIndexChanged is fired when an item is selected, but also when an item is "unselected" (which would happen if the currently selected item is removed from the list). Add a check to verify that there is an item selected:
if (m_lbOPFfiles.SelectedIndex >= 0) // you can also use m_lbOPFfiles.SelectedItem != null
{
m_Txt.Clear();
ClassName fileInfo = new ClassName(m_lbOPFfiles.SelectedItem.ToString());
m_Txt.Multiline = true;
m_Txt.Text = fileInfo.title + Environment.NewLine + fileInfo.ID + Environment.NewLine + fileInfo.time;
}
If no item is selected SelectedIndex is -1, and SelectedItem is null.
My guess would be on the 3rd line of the lb_SelectedIndexChanged method.
You are calling ToString() on the SelectedItem which might be null at this point - after removing the item in line 7 of the m_btnUP_Click method it probably is null - and this will throw you the exception.
You can see in the exception details which line of code it was thrown from, and pin point the error like this. You can also debug the code line by line and see for yourself.
Hope this helps.
My guess would be that your Items.RemoveAt call is clearing the selection, causing SelectedItem to become null, and the lb_SelectedIndexChanged event to fire, where this null causes the problem you describe.
I suggest you make sure in the event handler that something is actually selected.

Categories