Object reference not set to an instance of an object c# - c#

I have a listbox and i'm trying to select an item to display a label. My code is as follows:
private void listBox2_MouseDown(object sender, MouseButtonEventArgs e)
{
ListBox lb = (ListBox)sender;
var selected = lb.SelectedValue.ToString();
//string selected = listBox2.SelectedItem.ToString();
label5.Visibility = Visibility.Visible;
if (selected.ToString() == "Study Date")
{
label5.Content = "Format:YYYYMMDD";
}
if (selected.ToString() == "Patient's Name") label5.Content = "Enter name in string format.";
}
But when i click on an item, i get an error as: Object reference not set to instance of an object. I cannot enter the code in the Selection changed event, so please tell me how I can go about this. Thanks!

You have a potential issue here:
var selected = lb.SelectedValue.ToString();
You are calling ToString() even though SelectedValue can be null
Before you call ToString() make sure SelectedValue is not null

IIRC the MouseDown() event fires before the selection is registered. Wouldn't you be better off using the SelectionChanged() event?

Related

How to get current row of datagridview values when clicking on button?

I have a View Model in which my data is stored to be used on the presenter and window. However, I now need to get (when pressing a button) the current row's results on the grid into my view model. I first used the mouse double click event, but the requirements changed from that to a button on the form:
private void dgvResults_CellMouseDoubleClick(object sender, DataGridViewCellMouseEventArgs e)
{
if (this.colOrderNo.Index != e.ColumnIndex || e.RowIndex < 0) return;
var auditOrder = (PurchaseOrdersTrackingViewModel) this.dgvResults.Rows[e.RowIndex].DataBoundItem;
this.AuditOrderKey = $"{auditOrder.OrderNo}|{auditOrder.ItemNo}|{auditOrder.WarehouseId}|{auditOrder.ItemSequence}";
}
That's my old code. Now I need that here:
private void btnAuditLog_Click(object sender, EventArgs e)
Not sure how to refer to the RowIndex without the DataGridViewCellMouseEventArges event. I tried the CurrentRow property, but it doesn't do the job.
Just another question on the fly, if someone could assist with that as well, how do I get a value from one form to another, spesifically a properties value. It's not on the grid, in a control. It's basically just public string order that's all. I set the value on one form, then need it for query filtering on another. Let me know if you need anything else.
You want to use the SelectedRows property of the DataGridView. It tells which row is selected. In this case, you seem to want the first selected row (since you have a single property called this.AuditOrderKey).
The column order no to longer matters in this context.
if (dgvResults.SelectedRows.Count == 0) return;
var auditOrder = (PurchaseOrdersTrackingViewModel) dgvResults.SelectedRows[0].DataBoundItem;
this.AuditOrderKey = $"{auditOrder.OrderNo}|{auditOrder.ItemNo}|{auditOrder.WarehouseId}|{auditOrder.ItemSequence}";
If you don't have selected rows, CurrentRow is an option:
if (dgvResults.CurrentRow == null) return;
var auditOrder = (PurchaseOrdersTrackingViewModel) dgvResults.CurrentRow.DataBoundItem;
this.AuditOrderKey = $"{auditOrder.OrderNo}|{auditOrder.ItemNo}|{auditOrder.WarehouseId}|{auditOrder.ItemSequence}";
Use the SelectedRows property of the DataGridView. Assuming that you set your DataGridView as MultiSelect = false; and SelectionMode = FullRowSelect;
if (dgvResults.SelectedRows.Count > 0)
{
dgvResults.SelectedRows[0].Cells["yourColumnName"].Value.ToString();
}
In your button click event, it will look like this. (Assuming that your button name is btnEdit)
private void btnEdit_Click(object sender, EventArgs e)
{
if (dgvResults.SelectedRows.Count > 0)
{
string selectedValue = dgvResults.SelectedRows[0].Cells["yourColumnName"].Value.ToString();
}
}

How to access repository combobox value in XtraGrid column

I have a XtraGrid GridControl defined with 3 columns, 2 databound and one I have set to a RepositoryItemComboBox. The column is setup like:
this.gridColumn3.Caption = "Test";
this.gridColumn3.FieldName = "test";
this.gridColumn3.Name = "gridColumn3";
this.gridColumn3.UnboundType = DevExpress.Data.UnboundColumnType.String;
this.gridColumn3.Visible = true;
this.gridColumn3.VisibleIndex = 2;
The RepositoryItemComboBox is created like:
RepositoryItemComboBox cbo = new RepositoryItemComboBox();
cbo.Items.Add("1");
cbo.Items.Add("2");
cbo.Items.Add("3");
cbo.Items.Add("4");
cbo.Items.Add("5");
cbo.Items.Add("6");
cbo.Items.Add("7");
gridView1.Columns[3].ColumnEdit = cbo;
When viewing the grid, the combobox displays exactly as I want it. This issue is when trying to retrieve the value selected in the combobox. When a button, outside of the grid, is pressed the combobox value should be processed. I use the following code:
for (int i = 0; i < gridView1.DataRowCount; i++)
{
int ID = (int)gridView1.GetRowCellValue(i, "id");
string Test = gridView1.GetRowCellValue(i, "test").ToString();
ProcessCombo(ID, Test);
}
In the above code ID is retrieved as expected, but gridView1.GetRowCellValue(i, "test") returns null. What could I have missed out? Is this even the right way to approach this?
ComboBox editor is only exists when the focused cell is in editing state. So, ComboBox is created when you activate it and is destroyed when you go away. So, when your Button is pressed there are no ComboBox in your GridView.
If you want to get the ComboBox value then you need to use events of your RepositoryItemComboBox or editing events of your GridView. The link to the editor is stored in sender parameter of RepositoryItemComboBox events and in GridView.ActiveEditor property. The value of the ComboBox you can get by using ComboBox.EditValue property or by using GridView.EditingValue property. Also you can get the value by using EventArgs parameter of GridView editing events like ValidatedEditor, CellValueChanging, CellValueChanged.
For example:
private void RepositoryItemComboBox1_Closed(object sender, ClosedEventArgs e)
{
//Get the value from sender:
var comboBox = (ComboBoxEdit)sender;
object value = comboBox.EditValue;
//Get the value from active editor:
object activeEditorValue = gridView1.ActiveEditor.EditValue;
//Get the value from editing value:
object editingValue = gridView1.EditingValue;
}
Also, if you want to store your value and use it later then you can use ColumnView.CustomUnboundColumnData event.
Here is example:
private Dictionary<int, string> _comboBoxValues = new Dictionary<int, string>();
private void gridView1_CustomUnboundColumnData(object sender, CustomColumnDataEventArgs e)
{
if (e.Column.FieldName != "test")
return;
int id = (int)gridView1.GetListSourceRowCellValue(e.ListSourceRowIndex, "id");
if (e.IsSetData)
_comboBoxValues[id] = (string)e.Value;
else if (e.IsGetData && _comboBoxValues.ContainsKey(id))
e.Value = _comboBoxValues[id];
}
I decided to change the column to a bound field, passed in an empty string when populating the grid, and now I can access the data via:
string Test = gridView1.GetRowCellValue(i, "test").ToString();
Didn't want to do this, but it works so...

Can't get value from ComboBox control

I try to use combobox in winforms project.
Here is my code:
private void ShowContoursForm_Load(object sender, EventArgs e)
{
cbxSelectShape.DisplayMember = dataSetObject.ObjectShapes.ShapeNameColumn.ColumnName;
cbxSelectShape.ValueMember = dataSetObject.ObjectShapes.ShapeIDColumn.ColumnName;
cbxSelectShape.DataSource = dataSetObject.ObjectShapes;
}
private void cbxSelectShape_SelectedValueChanged(object sender, EventArgs e)
{
var id= (int)cbxSelectShape.SelectValue;
}
When I choose item from ComboBox SelectedValueChanged is fired,and id variable gets null.
I need to get value of selected item but I always get null in id variable.
Any idea why do I get wrong result and how to fix this code?
You can get the index of ComboBox this way:
private void cbxSelectShape_SelectedValueChanged(object sender, EventArgs e)
{
var id= ((ComboBox)sender).SelectedIndex;
}
You should use SelectedValue property of combobox to get value, associated with ValueMember (ShapeID in your case):
var id = ((ComboBox)sender).SelectedValue;
SelectedIndex returns index of item selected in combobox. Also if this handler used for one combobox, you don't need to cast sender - simply use your combobox variable:
var id = cbxSelectShape.SelectedValue;

WPF C# NULL exception on combobox selection change

This is selection changed event :
private void cbUsers_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
SelectedUser = (sender as ComboBox).SelectedItem.ToString();
GetUserInformation();
}
GetUserInformation is just selecting password from database. Users are deleted from the database and then the following refreshes the ComboBox items:
public void FillComboBox()
{
cbUsers.ItemsSource = null;
HProDataContext db = new HProDataContext();
var _UserName = (from d in db.users select d.username).ToList();
cbUsers.ItemsSource = _UserName;
}
HProDataContext db = new HProDataContext();
var _UserID = (from d in db.users where d.username == cbUsers.Text select d.id).SingleOrDefault();
user u = db.users.Single(p => p.id == _UserID);
db.users.DeleteOnSubmit(u);
db.SubmitChanges();
cbUsers.ItemsSource = null;
cbUsers.Text = null;
FillComboBox();
When using this last method it gives such error:
Object reference not set to an instance of an object.
The error falls on this line of the FillComboBox method:
SelectedUser = (sender as ComboBox).SelectedItem.ToString();
Does anyone have an idea as to what is wrong?
I'd guess that SelectedItem is null and therefore you're calling ToString on nothing.
Consider trying this:
if ((sender as ComboBox).SelectedItem != null)
{
SelectedUser = (sender as ComboBox).SelectedItem.ToString();
}
However, doesn't your ComboBox have an identifier? This can allow you to refrain from unnecessary conversions with as:
if (myComboBox.SelectedItem != null)
{
SelectedUser = myComboBox.SelectedItem.ToString();
}
Your event handler is probably getting called when there is no SelectedItem.
I would write this as:
private void cbUsers_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var usersComboBox = (ComboBox)sender;
if (usersComboBox.SelectedItem == null) return;
SelectedUser = usersComboBox.SelectedItem.ToString();
GetUserInformation();
}
Here you are expecting that sender is always a ComboBox, so I would use a cast instead of as. The exception will let you know if your assumption is wrong.
This will just skip your code if the event handler is called without a selected item.
One possibility is that sender might not be a ComboBox.
A problem of using an as operator without a null check is you get a NullReferenceException instead of a InvalidCastException which is more appropriate
Use an explicit cast instead e.g. ((ComboBox)sender).SelectedItem.ToString(); if you are sure sender is a ComboBox; otherwise check for null before usage.

Comboboxes only load when selecting the second items and below

This is really strange. I want to select a State and load Cities from that State in another combobox.
It's working EXCEPT when selecting the first item in the combobox:
Here's my entire class. The if statement in the selectedIndexChanged is to make sure that something is selected. The problem is that if I set that to cmbState.SelectedIndex >= 0 then an exception is raised because on initial load the comboBox doesn't has a .State variable there and not a .Value.
I don't know if this makes any sense.
private void MainForm_Load(object sender, EventArgs e)
{
LoadDepartmentsToComboBox();
}
private void LoadCitiesToComboBox(long StateID)
{
cmbCity.DataSource = null;
CityRepository cityRepo = new CityRepository();
cmbCity.DataSource = cityRepo.FindAllCities().Where(c => c.IDState == StateID);
cmbCity.DisplayMember = "Name";
cmbCity.ValueMember = "ID";
}
private void LoadDepartmentsToComboBox()
{
cmbState.DataSource = null;
StateRepository stateRepo = new StateRepository();
cmbState.DataSource = stateRepo.FindAllStates();
cmbState.DisplayMember = "Name";
cmbState.ValueMember = "ID";
}
private void cmbState_SelectedIndexChanged(object sender, EventArgs e)
{
if (cmbState.SelectedIndex > 0)
{
LoadCitiesToComboBox(Convert.ToInt64(cmbState.SelectedValue));
}
}
If I do use cmbState.SelectedIndex >= 0 then I receive this exception:
Unable to cast object of type
'DocumentScannerDanyly.State' to type
'System.IConvertible'.'System.IConvertible'.
When I don't use the SelectedIndex >= 0 and use plain old >0 then everything works except when selected the first item, which does nothing; understandably because it doesn't take the first item into account.
Thanks a lot for the help.
Don't assign the Display member & the Value member in each load, just assign them once in constructor for example.
add ToList() to the result which will assign to DataSource,
Complex DataBinding accepts as a data source either an IList or an IListSource.
check this.

Categories

Resources