DataGridView won't load - c#

I tried a lot to get around this problem,
Basically, I'm checking if someone has the same country id as the one set in the combobox, if so, I add some information regarding them on the DataGridView below,
but It seemed to not work, I debuged the conditions and all, but I still didn't know what could be wrong with it,
public partial class Form_ListJ : Form
{
public Form_ListJ()
{
InitializeComponent();
comboBox_ListJ.DataSource = Form_Menu.dataSet.Tables["Pays"];
comboBox_ListJ.DisplayMember = "nomPays";
comboBox_ListJ.ValueMember = "idPays";
comboBox_ListJ.SelectedIndex = -1;
}
private void comboBox_ListJ_SelectedIndexChanged(object sender, EventArgs e)
{
dataGridView_ListJ.Rows.Clear();
foreach (DataRow dataRow_J in Form_Menu.dataSet.Tables["Joueur"].Rows)
{
if (dataRow_J[7] == comboBox_ListJ.SelectedValue)
dataGridView_ListJ.Rows.Add(dataRow_J[0], dataRow_J[1], dataRow_J[2]);
}
}
}
dataRow_J[7] is the field of 'idPays' inside of the 'Joueur' table.

try to convert values to string
like this
if (dataRow_J[0].ToString() == comboBox1.SelectedValue.ToString())

Related

How know if the combobox was binding?

My code is:
private void cmbMaritalStatus_Click(object sender, EventArgs e)
{
if (cmbMaritalStatus.BindingContext==null)
{
cmbMaritalStatus.Text = string.Empty;
FillComboboxes();
}
}
public void FillComboboxes()
{
cmbMaritalStatus.SetBindingToLookup(dataSource);
cmbMaritalStatus.BindSelected(bscAssistanceFileModel, pnr.Get(x => x.AssistanceFile.MaritalStatus));
}
the object dataSource is type of IEnumerable<CDX_MaritalStatus>
and I want that if this Combobox not was Binding so I send it to function
that bind it.
I try this code but in the first time it's looks good
But when that I debug it and I see that it's full, it's enter to the if
although that it's was Binding
The solution is only flag??
I don´t know how you bind the data to the combobox. But you can try to check if the DataSource is null - like this:
DataSource source = cmbMaritalStatus.DataSource;
if (source.Count == 0)
{
cmbMaritalStatus.Text = string.Empty;
FillComboboxes();
}

ComboBox.SelectedValue not working as expected

So I have a DataGridView which I am using as a “row selector” on a form, and a bunch of controls are bound to the bindingSource.
One of the bound controls is a ComboBox serving as a lookup which enables status choices for the rows, this is populated from a DataTable with data pulled from the DB.
The population of this box is without any issue.
When a given row is selected from the DGV the form controls display data from the given row as they should, however the “statusComboBox” is not quite playing the game.
If in the DGV, I choose a row that has a different status to one previously selected, it works as it should, however, if I choose a row with the same value to a previously selected row, instead of the box showing the DisplayMember it shows the ValueMember.
IT only seems to occur in the above scenario, where the rows selection only instigates a display response from the bound ComboBox providng a previous selection had a different “Status ID”. What have I dont wrong that would cause this behaviour?
So the form load looks like this
private void ProjectsForm_Load(object sender, EventArgs e)
{
InitBindingSource();
//// bind Selector
//ASMod$ this needs to be 'true' unless you explicitly declare columns
ProjectsDataGridView.AutoGenerateColumns = false;
ProjectsDataGridView.DataSource = ProjectsBindingSource;
GetData();
//Set GeneralStatusBox
Helpers.GeneralStatusInitLookup(statusComboBox, ProjectsBindingSource);
}
The ProjectBindingSource is initialised thus:
private void InitBindingSource()
{
ProjectsBindingSource = new BindingSource();
projectsBindingNavigator.BindingSource = ProjectsBindingSource;
ProjectsBindingSource.PositionChanged += new EventHandler(ProjectsBindingSource_PositionChanged);
}
A ProjectsAddDataBindings procedure, and the contained DataBindings.Add for the ComboBox (executed at the end of a GetData routine that additionally populated ProjectsBindingSource):
ProjectsAddDataBindings();
{
…
this.statusComboBox.DataBindings.Add("Text", ProjectsBindingSource, "GSID");
…
}
After the GetData block the GeneralStatusInitLookup populates the Lookup elements, in a helper class simply because it provides functionality to a number of different forms
public static void GeneralStatusInitLookup(System.Windows.Forms.ComboBox comboBox, BindingSource primaryBindingSource)
{
string statusFilter = "";
statusFilter = Helpers.GetStatusGroupFilter(EndeavourForm.FilterId);
if (statusFilter != "")
{
statusFilter = " WHERE " + statusFilter;
}
//// string statusFilter = ""; //// temp
string sql = "";
sql = "SELECT GSID, ShortName FROM GeneralStatus" + statusFilter + " ORDER BY Pos";
GeneralStatusDataTable = Helpers.Db.GetDataTable(sql);
comboBox.DataSource = GeneralStatusDataTable;
comboBox.DisplayMember = "ShortName";
comboBox.ValueMember = "GSID";
comboBox.DataBindings.Add(new Binding("SelectedValue", primaryBindingSource.DataSource, "GSID"));
}
And the DGV initiated row change is handled like this
private void ProjectsBindingSource_PositionChanged(object sender, EventArgs e)
{
try
{
// Update the database with the user's changes.
UpdateProjects();
statusComboBox.SelectedValue = (int)CurrentDataRowView.Row["GSID"];
}
catch (Exception)
{
}
}
private void UpdateProjects()
{
try
{
ProjectsDataAdapter.Update((DataTable)ProjectsBindingSource.DataSource);
DataHelper.CommitProposedChanges(projectsDataSet);
if (this.projectsDataSet.HasChanges() == true)
{
ProjectsBindingSource.EndEdit();
ProjectsDataAdapter.Update();
}
CurrentDataRowView = (DataRowView)ProjectsBindingSource.Current;
}
catch (InvalidOperationException)
{
throw;
}
catch (Exception)
{
throw;
}
}
Anyway I hope I haven't swamped readers with to much code, but frankly I cant see where this is going wrong. So any help would be greatly appreciated.
This was a simple solution in the end. Both the GeneralStatusInitLookup() and the ProjectsAddDataBindings() blocks made use of DataBindings.Add ... For the lookup table this was fine, but with the binding to the main table; the later, I had used "Text" as the propertyName parameter.

c# getting specified cell (3rd column of last row) edited

I have posted a topic about this earlier, but since I have made some mistakes so I decided to post a new topic to make sure that my question is clear enough.
Here's my code :
private void button1_Click(object sender, EventArgs e)
{
if (dataGridView1.Rows.Count > 0)
{
int nRowIndex = dataGridView1.Rows.Count-1;
if (dataGridView1.Rows[nRowIndex].Cells[2].Value != null)
{
textBox2.Text = dataGridView1.Rows[nRowIndex].Cells[2].Value.ToString();
}
else
{
MessageBox.Show("NULL");
}
}
}
In my DataGridView, I have 3 columns which are ID, Name, Price.
I want to get the last cell of Price which is at the last row of the DataGridView.
The above code causes me to have NullReferenceException and the specified cell does have data in it.
Anyone know how to solve this problem?
Try this:
textBox2.Text = dataGridView1.Rows[nRowIndex].Cells["Price"].Value.ToString();
and report please.

How to go to last clicked on row in a datagridview

The following code is used to populate a DGV:
private void frmSwitch_Load(object sender, EventArgs e)
{
// TODO: This line of code loads data into the 'newCityCollectionDataSet.PropertyInformation' table. You can move, or remove it, as needed.
this.propertyInformationTableAdapter.Fill(this.newCityCollectionDataSet.PropertyInformation);
// TODO: This line of code loads data into the 'newCityCollectionDataSet.ClientTable' table. You can move, or remove it, as needed.
this.clientTableTableAdapter.Fill(this.newCityCollectionDataSet.ClientTable);
}
This code allows me to pass the necessary information to the "summary form":
private void propertyInformationDataGridView_CellContentDoubleClick(object sender, DataGridViewCellEventArgs e)
{
System.Data.DataRowView SelectedRowView;
newCityCollectionDataSet.PropertyInformationRow SelectedRow;
SelectedRowView = (System.Data.DataRowView)propertyInformationBindingSource.Current;
SelectedRow = (newCityCollectionDataSet.PropertyInformationRow)SelectedRowView.Row;
frmSummary SummaryForm = new frmSummary(this);
SummaryForm.LoadCaseNumberKey(SelectedRow.CaseNumberKey, true, null);
SummaryForm.LoadBRTNumberKey(SelectedRow.BRTNumber, null);
SummaryForm.Show();
}
What I am looking to do is pass the SelectedRow and add 1 to go to the next row if the current SelectedRow is no longer valid (for instance when FileFinishedCheckBox is checked on the "summary form"). I also want the same thing to happen anytime a checkbox is checked on the DataGridview so people do not have to scroll back to the file they are working on.
The code that performs the refresh whenever needed is as follows:
public void PerformRefresh()
{
this.propertyInformationBindingSource.EndEdit();
this.propertyInformationTableAdapter.Fill(this.newCityCollectionDataSet.PropertyInformation);
this.propertyInformationDataGridView.Refresh();
}
Any help would be great.
This question seems to be in two parts:
How to communicate between two windows forms
How to change the selected row in a datagridview
There are many different ways of achieving both tasks so I'm just going to give you two that will work. The first (for windows forms) is the simplest, while the second (for changing the selected row) is in my opinion the correct method.
Communication between windows forms
The most straightforward way to communicate between two windows forms is pass a reference to one form into the other form.
So say you have Form1 which opens Form2, you could do something like this:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
Form2 f = new Form2(this);
f.Show();
}
public void ShowMessage(string message)
{
MessageBox.Show(message);
}
}
public partial class Form2 : Form
{
private Form1 _parentForm;
public Form2(Form1 parentForm)
{
InitializeComponent();
_parentForm = parentForm;
_parentForm.ShowMessage("I am a message from form1);
}
}
So in your example you would add a method to the parent form which takes as its parameter the unique value for the row selected in dgv3 to show in gdv1. In the method (which is a member of the parentForm you put the centering code which I will show below).
Other ways of doing this include passing a delegate to the child form which is the method to center the datagridview. This has the advantage that you are no longer tied down to always passing in Form1 and can even provide different actions in resonse to the checkbox but is slightly more complicated to implement.
Centering on a selected record in a DataGridView
My preferred way of doing this is to use a bindingsource to provide the datasource for the grid. You can also directly access the grid position using the CurrentCell property but with the bindingsource you get a bit more bang for your buck.
In the code below we have a form which creates a BindingSource, sets its datasource to a BindingList of type MyBindingList and then sets the binding source as the datasource of a datagridview.
The objects within the BindingList have a unique property "PrimaryKey" allowing us to find them.
Then I show the centering code which is actually very simple.
First we get the index in the binding source of the desired you by calling the Find() method of the binding source.
Second we change the binding sources position (this also updates the datagridview display).
Finally we change the FirstDisplayedScrollingRowIndex of the datagridview so that the selected row is not at the very top or bottom of the grid (you will want to add a check to ensure this is a valid index if you use this line).
public partial class Form1 : Form
{
BindingSource bs;
public Form1()
{
InitializeComponent();
bs = new BindingSource();
MyBindingList<BackingObject> backing_objects = new MyBindingList<BackingObject>();
backing_objects.Add(new BackingObject{ PrimaryKey = 1, Name = "Fred", Hidden = "Fred 1"});
bs.DataSource = backing_objects;
dataGridView1.DataSource = bs;
}
private void button1_Click(object sender, EventArgs e)
{
int index = bs.Find("PrimaryKey", 5);
bs.Position = index;
dataGridView1.FirstDisplayedScrollingRowIndex = index - 1;
}
}
Now the last this to note is that bindinglist out of the box does not support the Find() method of the bindingsource. This is why I use my custom MyBindingList. Code to implement this can be found here.
Essentially you need a class like the following:
public class MyBindingList<T> : BindingList<T>
{
protected override bool SupportsSearchingCore
{
get
{
return true;
}
}
protected override int FindCore(PropertyDescriptor prop, object key)
{
// Get the property info for the specified property.
PropertyInfo propInfo = typeof(T).GetProperty(prop.Name);
T item;
if (key != null)
{
// Loop through the items to see if the key
// value matches the property value.
for (int i = 0; i < Count; ++i)
{
item = (T)Items[i];
if (propInfo.GetValue(item, null).Equals(key))
return i;
}
}
return -1;
}
}

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