Reputation: 579
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.
Upvotes: 1
Views: 3108
Reputation: 199
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
Upvotes: 1