Unable to access the fields of selecteditem on listview - c#

I have a listview on mouse double click i am trying to get the name and path of the item selected, I have written following code but i am getting "System.NullReferenceException" error
public class Listview_data
{
public string name
{
get;
set;
}
public ImageSource Image
{
get;
set;
}
public string path
{
get;
set;
}
};
private void ListView_MouseDClick(object sender, MouseButtonEventArgs e)
{
Listview_data lvd = null;
lvd = DocsListView.SelectedItem as Listview_data;
MessageBox.Show(lvd.name);
}
I have attached screenshot of debugging

According to screenshot DocsListView.SelectedItem is of type SimpleCube.Documents
so after this line of code lvd is null
lvd = DocsListView.SelectedItem as Listview_data;
And following line of code throws NullReferenceException when accessing lvd.name
MessageBox.Show(lvd.name)
So fix your bindings first

According to the debug image posted your code should be
private void ListView_MouseDClick(object sender, MouseButtonEventArgs e)
{
SimpleCube.Documents lvd = null;
lvd = DocsListView.SelectedItem as SimpleCube.Documents;
if(lvd != null)
MessageBox.Show(lvd.Name);
}
Or, perhaps, the setting of the Datasource for the ListView should be changed to a Listview_Data list of objects.

You should be checking that the SelectedItem is not null prior to use for example;
private void ListView_MouseDClick(object sender, MouseButtonEventArgs e)
{
Listview_data lvd = null;
lvd = DocsListView.SelectedItem as Listview_data;
if (lvd == null)
{
MessageBox.Show("You should only double click on an item");
return;
}
MessageBox.Show(lvd.name);
}
There is the possibility that the SelectedItem property will return null if there is no items selected. Also by casting using 'as' you can also get a null reference exception later on if the object isn't the correct type, although this probably isn't a likely scenario in this case.
John Skeet has written a good article on using 'as' for type casting and checking for null, definitely worth a read (Casting vs "as" - embracing exceptions).

Related

Checking if parameter has been passed in windows universal c# code

Am passing a parameter as a way to allow a user to go back and make changes
private void go_back_btn_Click(object sender, RoutedEventArgs e)
{
Frame.Navigate(typeof(TruckRegistrationPage), this.truckdetails);
}
Now on the trruck registration page
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
this.changeddetails= (TruckRegistrationDetails)e.Parameter;
//set the form fields based on the details
if (e.Parameter) //this throws an error of boolean not casted
{
truck_reg_no.Text = changeddetails.reg_no;
transporter_name.Text = truckdetails.owner_id;
.......assign other xaml controls
}
}
The parameters am passing are of type TruckRegistrationDetails whic is a class containing properties as below
class TruckRegistrationDetails
{
public int id { get; set; }
public string reg_no { get; set; }
public int truck_category { get; set; }
.......others
}
How do i check to see if any parameters have been passed and hence assign the xaml controls value
Change your code to this
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
changeddetails = (TruckRegistrationDetails)e.Parameter;
if (changeddetails != null)
{
truck_reg_no.Text = changeddetails.reg_no;
//do what ever you want ^^
}
}
Your check was for a boolean, but e.Parameter is an object. Here is the link to MSDN https://msdn.microsoft.com/de-de/library/windows/apps/windows.ui.xaml.navigation.navigationeventargs.parameter.aspx
I was getting an error using this approach as at some point OnNavigatedTo is called with a NavigationEventArgs.Parameter of an empty string. This was causing a Cast exception when the object is cast to the object type I passed.
I used:
if (args.Parameter is DeviceInformation)
{
DeviceInformation deviceInfo = (DeviceInformation)args.Parameter;
//Do something with object
}
This checks the type of object first to see if it matches the expected first, then the cast will not throw an exception.

How do I get notified when an array property changes?

My class contain many properties and i need to handle each properties.
See this below:
public partial class my_form : Form
{
private Image[] _imagelist;
public Image[] imagelist
{
get
{
return _imagelist;
}
set
{
this._imagelist = value;
this.on_imagelist_changed();
}
}
private void on_imagelist_changed()
{
// do something.
}
private void button1_Click(object sender, EventArgs e)
{
/* set new imagelist */
this.imagelist = getimagelist();
}
}
Yes, It's work fine.
But when i call like this.
public partial class my_form
{
private void listView1_MouseDoubleClick(object sender, MouseEventArgs e)
{
int selectedIndex = this.listView1.SelectedItems[0].ImageIndex;
this.imagelist[selectedIndex] = dosomething(this.imagelist[selectedIndex]);
}
}
It's don't call on_imagelist_changed(). Why ?
I can't add property by indexer like this. :(
public partial class my_form
{
public Image imagelist[int x]
{
get
{
return _imagelist[x];
}
set
{
this._imagelist[x] = value;
this.on_imagelist_changed();
}
}
}
Can anyone help me solve this problem ?
Can i avoid to make a control class like this C# Indexers ?
I founded some suggestion, they told me let try ObservableCollection. I don't understand about this. May be someone example for me ?
It's don't call on_imagelist_changed(). Why?
Because, quite bluntly, imageList has not changed. Some images inside imageList may have changed, but your code reacts only to the change of the entire imageList. The assignment calls get of your property twice; it never calls the setter.
I can't add property by indexer like this.
That's correct. However, you correctly noted that you could use an observable collection:
public ObservableCollection<Image> Images {get;}
private void OnImageListChanged(
object sender
, NotifyCollectionChangedEventArgs e) {
// do something.
}
public MyForm() {
Images = new ObservableCollection<Image>();
Images.CollectionChanged += OnImageListChanged;
}
Because your property gets and sets pointer to array, not array itself. So when you change array items pointer stays the same.
That's why properties should not return arrays.

Adding XML node on the basis of TextBox entry inside WPF Form

Suppose i have created a WPF form having one text box. i am calling that form inside another wpf window's gridpanel and after entering value inside the textbox, i am clicking on submit button. After button click, i need to get that value and save it in string form inside my current class. My logic is something like this.
For getting the from inside my current window:-
void SelectedClick(object sender, RoutedPropertyChangedEventArgs<object> e)
{
selectedItem.ContextMenu = VcontextMenu;
VcontextMenu.Items.Add(VmenuItem1);
VmenuItem1.Click += AddValidation;
details();
}
void AddValidation(object sender, RoutedEventArgs e)
{
ValidationForm obj = new ValidationForm();
ProcessGrid.Content = obj.VForm;
}
Now i want to store the value of my textbox inside a string. For that i have used following code:-
public void details()
{
ValidationForm obj = new ValidationForm();
string str = obj.s.ToString();
}
My ValidationForm Code:-
public partial class ValidationForm : UserControl
{
public string s { get; set; }
public ValidationForm()
{
InitializeComponent();
}
public void XSave_Click(object sender, RoutedEventArgs e)
{
s = TextValidationName.Text;
}
}
but instead of opening the form, the control is going to obj.s.ToString() and showing error as "Object reference not set to an instance of an object." Please help. Thanks.
The issue is caused since the string s in your ValidationForm class is not assigned. It is probably caused since the XSave_Click() method is not being called.
Ensure that you properly assign the value to s before you try to get value from it.

What will be displayed by the MessageBox?

I Have Code for EventHandler like this below.
I do not know what is meant by e.Value, can someone explain and show approximately what will be displayed by the MessageBox?
void ConnectionManager_Error(object sender, EventArgs<string> e)
{
BeginInvoke((MethodInvoker)delegate()
{
State = ConnectState.NotFound;
MessageBox.Show(e.Value);
});
}
Note:
I have this code that I thought would trigger ConnectionManager Error EventHandler.
private void LogError(string error)
{
if (Error != null)
Error(this, new EventArgs<string>(error));
}
I also have this code that gives an error message containing the string to LogError method.
int lasterror = Marshal.GetLastWin32Error();
if (lasterror != 0)
LogError("Bluetooth API returned: " + lasterror.ToString());
or
if (BluetoothSetServiceState(IntPtr.Zero, ref device, ref HumanInterfaceDeviceServiceClass_UUID, BLUETOOTH_SERVICE_ENABLE) != 0)
LogError("Failed to connect to wiimote controller");
Another Hint
To be more specific, I also already have the code below:
public event EventHandler<EventArgs<string>> Error;
and
ConnectionManager.Error += new EventHandler<EventArgs<string>>(ConnectionManager_Error);
And also this class:
public class EventArgs<T> : EventArgs
{
public T Value
{
get;
set;
}
public EventArgs(T value)
: base()
{
Value = value;
}
}
But MessageBox never appears even when the device is not connected to the computer.
I think that comes MassageBox supposed that show error messages.
Can someone show me what is wrong?
Your ConnectionManager has Error event, which passes instance of EventArgs<string> to event handlers. I believe generic event argument looks like:
public class EventArgs<T> : EventArgs
{
public EventArgs(T value)
{
Value = value;
}
public T Value { get; private set; }
}
So, ConnectionManager sets some string value to this argument of event and passes it to ConnectionManager_Error event handler. You should see value which was passed. From event name I can assume it should be error message.
NOTE: ConnectState enum, State property of ConnectionManager and its StateChanged event is not related to code you work with.
A Message Box is shown with the value provided by the EventArgs. I can only assume that your EventArgs class is a generic EventArgs implementation where the type parameters defines the type of the value.
So whatever the value is, that is what you will see in the MessageBox.

Access components c#

I'm wondering about why can I access text from, for example, a combobox from outside the main class. But I can't add items to it.. the modifier of my combobox is set to public
public class ImageManager : mainFrame // Where my components are located
{
public ImageManager()
{
}
public void getText()
{
Console.WriteLine(comboBox.Text); //Will perfectly retrieve the text from it
}
public void setItem()
{
comboBox.Items.Add("Items"); //Does absolutely nothing and doesn't show error
}
}
Thanks for help !
What if your setItem() populated a ComboboxItem and added it instead of just text?
public void setItem()
{
ComboboxItem addMe = new ComboboxItem();
addMe.Text = "your text here";
addMe.Value = 1234; // make a relevant value
comboBox.Item.Add(addMe);
}
I see you got it working, great. But just in case your still scratching your head...
private void Form1_Load(object sender, EventArgs e)
{
ImageManager im = new ImageManager();
im.Show();
im.setItem();
}
ImageManager inherits from Form2 which has the comboBox. Seemed to work fine. comboBox got populated.

Categories