i have 2 question...
1. i have a gridview that bind some data form database that way
DataSource = Company.GetAllCompany();
dgvCompanys.AutoGenerateColumns = false;
dgvCompanys.DataSource = _DataSource;
dgvcolNameEn.DataPropertyName = "MyEnglishName";
dgvcolAddress.DataPropertyName = "MyAddress";
dgvcolCode.DataPropertyName = "MyCode";
dgvcolKeyId.DataPropertyName = "MyKeyId";
it's worked now i want get the KeyId of selected row
private void dgvCompanys_SelectionChanged(object sender, EventArgs e)
{
if (dgvCompanys.SelectedRows.Count > 0)
{
mtxtCode.Text=dgvCompanys.SelectedRows[0].Cells[1].Value.ToString();
}
}
this code have this error Object reference not set to an instance of an object.
what i have to do for this?
question 2.i have textboxdropdownlist(devComponent)
and sourced that way:
List<Company> _DataCompany;
_DataCompany = Company.GetAllCompany();
cmbCompany.DisplayMember = "MyEnglishName";
cmbCompany.DataSource = _DataCompany;
that worked correctly but i want get KeyId of rows selected in dropdown now what i have to do?
Question 1 : perhaps your dataset have only one column, so the right code is :
dgvCompanys.SelectedRows[0].Cells[0].Value.ToString();
Question 2 is not clear for me, but you can access to the selected item with :
DropDown.SelectedItem.ToString()
Related
I am working on a Windows forms application. I have two combo boxes, one to select the profile and the other to select the type of matrix. Each profile has a number of matrices which needs to be displayed in the combo box and set to the first matrix as default when the form loads.
I have set the data source and assigned the DisplayMember and Value member properties to both the combo boxes. However, when the form loads, in the second combo box where the different types of matrices should be listed, I have only System.Data.DataRowView for all the values. However, when I select the profile from the first comboBox, the second box is refreshed and the values are displayed correctly.
The code for the Profile comboBox
ddProfile.DataSource = dtProfile;
ddProfile.ValueMember = "ID";
ddProfile.DisplayMember = "Description";
ddProfile.Enabled = dtProfile.Rows.Count > 1;
foreach (DataRow dr in dtProfile.Rows)
{
if (dr["Ordinal"].ToString() == "1")
{
ddProfile.SelectedValue = dr["ID"];
break;
}
}
Code for the matrix comboBox
DataTable dtMatrix = new DataTable();
dtMatrix = DBConnector.GetTable("RiskMatrixList", "*", "", $"Profile={ddProfile.SelectedValue}", DBConnector.ConnectionType.Templates);
dtMatrix = DBConnector.GetTable($"SELECT * FROM RiskMatrixList WHERE Profile={ddProfile.SelectedValue}");
ddRiskMatrix.DataSource = dtMatrix;
ddRiskMatrix.DisplayMember = "Description";
ddRiskMatrix.ValueMember = "ID";
ddRiskMatrix.Enabled = dtMatrix.Rows.Count > 1;
foreach (DataRow dr in dtMatrix.Rows)
{
if (dr["IsDefault"].ToString() == "1")
{
ddRiskMatrix.SelectedValue = dr["ID"].ToString();
break;
}
}
Why am I not getting the right values when the form loads?
I observed that combo_SelectedValueChanged is called twice, when ValueMember and DisplayMember are being assigned, and then - I had the same problem.
After one day of very productive work :/ I discovered the trick:
1/ Added flag to form's properties:
public partial class frmMain : Form
{
bool IsLoadingCombo = false;
2/ Simply modified combo_SelectedValueChanged:
private void cbFilter_SelectedValueChanged(object sender, EventArgs e)
{
if (isLoadingCombo)
return;
// rest of method's code
}
Not very elegant, but better than wasting the next few days.
I think, that problem is that "rest of method's code" needs selected value which is unknown, when the method is stupidly triggered when disp/value members are being asigned.
I have two combo box ( say cbo_zone & cbo_floor ) which are having table as the data source
private void load_cbo_zone()
{
clz_Common_References ccr = new clz_Common_References ();
DataTable dt_zone = ccr.get_zone_detail();
cbo_zone.DataSource = dt_zone;
cbo_zone.ValueMember = "ID";
cbo_zone.DisplayMember = "zone";
cbo_zone.SelectedIndex = -1;
}
`
private void load_cbo_floor()
{
int ID_zone_ref = Convert.ToInt16(cbo_zone.SelectedValue);
clz_Common_References ccr = new clz_Common_References();
DataTable dt_flr = ccr.get_floor_data_fr_Ref_IDZone(ID_zone_ref);
cbo_floor.DataSource = dt_flr;
cbo_floor.DisplayMember = "Floor";
cbo_floor.ValueMember = "ID";
cbo_floor.SelectedIndex = -1;
}
` . I wrote the code to update the cbo_floor as following .
private void cbo_zone_SelectionChangeCommitted(object sender, EventArgs e)
{
load_cbo_floor();
}
Now I need to update the cbo_zone & cbo_floor when I click a data row of datagridview .
int ref_area_id, ref_floor_id, ref_zone_id;
int.TryParse(dt_issued_mat.Rows[0][11].ToString(), out ref_area_id);
DataTable dt_area_detail = ccr.get_area_data_fr_area_id(ref_area_id);
int.TryParse(dt_area_detail.Rows[0][2].ToString(), out ref_floor_id);
DataTable dt_floor_detail = ccr.get_floor_data_fr_floor_id(ref_floor_id);
int.TryParse(dt_floor_detail.Rows[0][2].ToString(), out ref_zone_id);
DataTable dt_zone_detail = ccr.get_zone_data_fr_zone_id(ref_zone_id);
after that using
cbo_zone.Text = dt_zone_detail.Rows[0][1].ToString();
cbo_floor.Text = dt_floor_detail.Rows[0][1].ToString();
I was able to display the values on the combo boxes but once I tried to get the cbo_floor.SelectedValue code doesn't work .
Then I was able to get the relevant SelectedIndex by using ,
int index = cbo_zone.FindString(dt_zone_detail.Rows[0][1].ToString());
cbo_zone.SelectedIndex = index ;
still the combo box shows nothing & "cbo_zone.SelectedValue" doesn't
show a value.my target is to get the cbo_floor.SelectedValue .
Please help .
Instead of cbo_zone.Text = dt_zone_detail.Rows[0][1].ToString();
cbo_floor.Text = dt_floor_detail.Rows[0][1].ToString();
Use
cbo_zone.Items.Add( dt_zone_detail.Rows[0][1].ToString());
cbo_floor.Items.Add ( dt_floor_detail.Rows[0][1].ToString());
First working with indexes is not a good idea. You have the value, use them. Using the index will cause you trouble.
cbo_zone.SelectedValue = myValue.ToString();//find the value from your data
Secondly for selecting the floor, you need to fill it with the relevant values first, since it already has the data for the last selection.
load_cbo_floor();
cbo_floor.SelectedValue = myValue.ToString();//find the value from your data
Ok, very dumb question but i haven't really found an answer on internet.
I have multiple comboboxes on a form. The binding of each combobox is on form_load.
When the form loads, the first item is selected on the form. This is obvious, but I don't want this. So i used in the form_load the following code:
private void InvoiceView_Load(object sender, EventArgs e)
{
// Bind list of customers to combobox
CustomerComboBox.DataSource = invoicePresenter.getCustomers();
CustomerComboBox.DisplayMember = "CustomerName";
CustomerComboBox.ValueMember = "CustomerId";
// Bind list of products to combobox
productCombobox.DataSource = invoicePresenter.getProducts();
productCombobox.DisplayMember = "ProductName";
productCombobox.ValueMember = "ProductId";
// Bind list of vat codes to combobox
vatComboBox.DataSource = invoicePresenter.getTaxCodes();
vatComboBox.DisplayMember = "taxCodeShortDescr";
vatComboBox.ValueMember = "taxCodeId";
// Set comboboxes empty
CustomerComboBox.SelectedItem = null;
productCombobox.SelectedItem = null;
vatComboBox.SelectedItem = null;
}
This works. But the textboxes are still giving me the data of the first item ? My guess is because its in the selectedIndexChanged. But i have no clue what to use else.
If I put the combobox.selectedIndex = -1; I face the same issue.
the code:
private void CustomerComboBox_SelectedIndexChanged(object sender, EventArgs e)
{
// Bind the selected customer itemvalues to the texboxes
txtCustomerName.Text = ((tbl_customer)CustomerComboBox.SelectedItem).CustomerName.ToString();
txtAddress.Text = ((tbl_customer)CustomerComboBox.SelectedItem).CustomerAddress.ToString();
txtPostalCode.Text = ((tbl_customer)CustomerComboBox.SelectedItem).CustomerPostalCode.ToString();
txtCity.Text = ((tbl_customer)CustomerComboBox.SelectedItem).CustomerCity.ToString();
txtCountry.Text = ((tbl_customer)CustomerComboBox.SelectedItem).CustomerCountry.ToString();
txtVatNumber.Text = ((tbl_customer)CustomerComboBox.SelectedItem).CustomerCountryCode.ToString() + ((tbl_customer)CustomerComboBox.SelectedItem).CustomerVat.ToString();
}
One would think, because im using selecteditem in the textbox binding, it would be null also. But this is not the case.
Interestingly, seems like you've hit one of the WF data binding quirks. The problem is caused by the fact that the CurrencyManager class which maintains every list data source does not allow setting the Position property to -1 (thus Current to null) when the list count is not zero. Since the ComboBox is synchronizing the SelectedIndex with the CurrencyManager.Position, this effectively prevents having an unselected item.
As a workaround, if the data bound mode of the list portion is not essential for you, replace the line
CustomerComboBox.DataSource = invoicePresenter.getCustomers();
with
foreach (var customer in invoicePresenter.getCustomers())
CustomerComboBox.Items.Add(customer);
Do the same for the other comboboxes that need such behavior.
You can remove the handler for the SelectedIndex_Changed event of combobox, bind data, then add the handler back. like this :
private void InvoiceView_Load(object sender, EventArgs e)
{
this.CustomerComboBox.SelectedIndexChanged -= new EventHandler(CustomerComboBox_SelectedIndexChanged);
this.productCombobox.SelectedIndexChanged -= new EventHandler(productCombobox_SelectedIndexChanged);
this.vatComboBox.SelectedIndexChanged -= new EventHandler(vatComboBox_SelectedIndexChanged);
// Bind list of customers to combobox
CustomerComboBox.DataSource = invoicePresenter.getCustomers();
CustomerComboBox.DisplayMember = "CustomerName";
CustomerComboBox.ValueMember = "CustomerId";
// Bind list of products to combobox
productCombobox.DataSource = invoicePresenter.getProducts();
productCombobox.DisplayMember = "ProductName";
productCombobox.ValueMember = "ProductId";
// Bind list of vat codes to combobox
vatComboBox.DataSource = invoicePresenter.getTaxCodes();
vatComboBox.DisplayMember = "taxCodeShortDescr";
vatComboBox.ValueMember = "taxCodeId";
this.CustomerComboBox.SelectedIndexChanged += new EventHandler(CustomerComboBox_SelectedIndexChanged);
this.productCombobox.SelectedIndexChanged += new EventHandler(productCombobox_SelectedIndexChanged);
this.vatComboBox.SelectedIndexChanged += new EventHandler(vatComboBox_SelectedIndexChanged);
}
I have a devexpress gridcontrol with 5 columns. The first column is a lookupedit repository with some data, let say with CarTypes.
To load data in grid I am using a BindingSource. In this BindingSource.DataSource I have load a IList<Cars>
and then
added this binding source in dataSource of my gridcontrol
like bellow
BindingSource _carsBindingSource = new BindingSource();
private void BindData(IList<Cars> data)
{
_carsBindingSource.DataSource = data;
carsGridControl.BeginUpdate();
carsGridControl.DataSource = _carsBindingSource;
carsGridControl.RefreshDataSource();
carsGridControl.EndUpdate();
}
I have a button to add new line in my grid "Add new car" and add a new line in _carBindingSource
private void AddNewRow()
{
_newRow = true;
_carsBindingSource.AllowNew = true;
Cars newCar = new Cars();
newCar.CarType = new CarType();
_carsBindingSource.Add(newCar );
//_carsBindingSource.Insert(0,newCar);
}
Now I want to add the new line in the first row of grid.
I use Insert
_carsBindingSource.Insert(0,newCar);
But it didn't work. The lookupedit repository can't load data.
With _carsBindingSource.Add(newCar); it works fine
Can anyone help me? Thank you!
If you haven't already, consider using an intermediate list for your car types:
private List<CarTypes> _CarTypes;
// Elsewhere in the code...
_CarTypes = GetCarTypes();
And then in the form load event, be sure this is bound to the data source:
repositoryLookupItemCarTypes.DataSource = _CarTypes;
With this, the grid should now automatically manage the instantiation and selection of the CarType object for each Cars object. You can omit this line when you add a car to the grid:
newCar.CarType = new CarType();
In the designer, I think it helps to alter the DisplayMember Property of the repository Item.
With this setup, any Car added to your grid should automatically have the CarType as a populated Lookup Edit.
If any of this is unclear, let me know. I did a quick and dirty solution to test this, and I obviously can't post it all, but I can tell you it did work with both Add and Insert.
Actualy I found a solutions.
The problem was in GridView_CustomRowCellEdit(object sender, CustomRowCellEditEventArgs e) event
where I change the AllowEdit value (e.Column.OptionsColumn.AllowEdit = true;).
private void gridView_CustomRowCellEdit(object sender, CustomRowCellEditEventArgs e)
{
string cName = e.Column.FieldName;
GridView gv = sender as GridView;
if (cName == "CarType.IdApi")
{
if (isNewRow)
{
Cars cars= (Cars)gv.GetRow(e.RowHandle);
int a = e.RowHandle;
if (cars.ID== 0 && e.RowHandle == 0)
{
e.Column.OptionsColumn.AllowEdit = true;
}
else
{
e.Column.OptionsColumn.AllowEdit = false;
}
}
}
}
When I use Insert(0, new Car) then because of second row whitch has value
the AllowEdit was false;
So I remove else code and it works
private void gridView_CustomRowCellEdit(object sender, CustomRowCellEditEventArgs e)
{
string cName = e.Column.FieldName;
GridView gv = sender as GridView;
if (cName == "CarType.IdApi")
{
if (isNewRow)
{
Cars cars= (Cars)gv.GetRow(e.RowHandle);
int a = e.RowHandle;
if (cars.ID== 0 && e.RowHandle == 0)
{
e.Column.OptionsColumn.AllowEdit = true;
}
}
}
}
So finlay I found that bindingSource.Add(object) and bindingSource.Insert(0,object) is same!
I apologize for my english!!
First of all, I must mention that I have seen this question, but it didn't help me to fix my problem.
According to my previous question, I saved my DataGridView to an XML file. Now I am going to fill the DataGridView when I load the window form using the data stored on the XML file.
My problem is that when I want to set the value of one ComboBox based on the stored data, the other ComboBox's value changes too. I want to set each ComboBox's value separately.
My code is as follows :
private void WindowSelection_Load(object sender, EventArgs e)
{
dataGridSource = DeserializeFromXML();
foreach (WindowHolder obj in dataGridSource)
{
int index = dataGridViewWindowSelection.Rows.Add();
DataGridViewComboBoxColumn combo2 = new DataGridViewComboBoxColumn();
combo2 = (DataGridViewComboBoxColumn)dataGridViewWindowSelection.Rows[index].Cells["Reader"].OwningColumn;
combo2.DataSource = readerSource;
int readerSourceIndex = findReaderSourceIndex(obj.reader);
if (readerSourceIndex != -1)
{
combo2.DefaultCellStyle.NullValue = readerSource[readerSourceIndex];
}
else
{
combo2.DefaultCellStyle.NullValue = readerSource[0];
}
dataGridViewWindowSelection.Rows[index].Cells["Location"].Value = obj.location;
dataGridViewWindowSelection.Rows[index].Cells["AlwaysOnTop"].Value = obj.alwaysOnTop;
dataGridViewWindowSelection.Rows[index].Cells["AlwaysShow"].Value = obj.alwaysShow;
}
}
Do you mean the line where you're changing combo2.DefaultCellStyle?
This happens because combo2.DefaultCellStyle is a reference to the default cell style of all the combos, so you're not changing this one combo - you're changing the common default style.
If you want the style of this combo to be different from the default one (and from the other combos' style), you should probably create a separate style and set it as the style of combo2.
I guess the statement should look something like combo2.DefaultCellStyle = ... or combo2.SetDefaultCellStyle( ... )