I need to get the currently selected object from da databound DataGridView.
I do not need the object of the current selected cell, but the object on which the whole row is based, in this case a BusinessObject whos properties make the columns of the grid.
I could go over the DataSource, but that itself is just an object and can be a BindingSource or a IBindingList or something like that - so not easy standartized way to get the wanted object.
Behind that is the need to just check the businessObject for a property called IsChanged and ask the user to save or discard the changes, before the bindingsource selects the next item. Therefore I must find out the current object inside RowValidating-Event of the DataGridView, since the BindingSource does not offer an event to stop changing before change occurs.See here for the well known problem
Thanks for reading ;-)
DataGridViewRow.DataBoundItem contains the 'business' object it is bound to.
Here is my code put this into your Person class
public static explicit operator Person(DataRow dr)
{
Person p = new Person();
p.adi = dr.ItemArray[0].ToString();
p.id = Int32.Parse(dr.ItemArray[1].ToString());
p.soyadi = dr.ItemArray[2].ToString();
p.kartNo = dr.ItemArray[3].ToString();
p.dogumTarihi = DateTime.Parse( dr.ItemArray[4].ToString() );
p.adres = dr.ItemArray[5].ToString();
p.meslek = dr.ItemArray[6].ToString();
p.telefon = dr.ItemArray[7].ToString();
p.gsm = dr.ItemArray[8].ToString();
p.eposta = dr.ItemArray[9].ToString();
return p;
}
and this is a update button click
DataRow row = (dataGridView1.SelectedRows[0].DataBoundItem as DataRowView).Row;
Person selected = (Person)row;
You can also use this short code.
Person selected = dataGridView1.SelectedRows[0].DataBoundItem as Person;
What about this way?
foreach (DataGridViewRow item in this.dataGridView1.SelectedRows)
{
MessageBox.Show(item.Cells[0].Value.ToString());
}
We can get multiple selected rows data.
Since you did state the IBindingList - yes as others have said the DataBoundItem property will give you what you need - there is an issue with it that I had experienced previously and ended up with a null reference but right now I can not think of the scenario in which it happened.
If you are databound using a BindingSource - you can capture the CurrentChanged, CurrentItemChanged events of your BindingSource , then you need not have an additional IsChanged Property on your B.O. .. , also the underlying datasource could also indicate modified - for example if you have BindingSource bound to a datatable the row would give you a modified flag.
You can get the selected cell value like this
yourDGV.CurrentCell.Value;
If you want the value in the form of a String just use ToString() method like this
yourDGV.CurrentCell.Value.ToString();
This should do it
Related
I have this problem for days and can't find solution for it. I tried all possible solutions i found on internet, but seems like none suits this one.
Thing is that i added repository item to gridControls (i added it through designer, not through code). Then, in code i added data source to that repository lookUpEdit and i have items in dropDown in that column. But when i select item in repository and click on other cell, Selected item in repository is cleared and repository shows null value again...
Any ideas what i did wrong ?
EDIT:
Also, when i click on any cell in my grid, i have delay of second or two, and after that delay clicked cell is focused... Any solutions for all of this?
EDIT:
Don't know what code to show You, because I did all in devExpress designer. Here is part of the code where I set data source to repository item, and i will give You code from designer of that repository item.
private void ConfigureRepositoryItems()
{
BetService.SportManagerClient dbSportManager = new BetService.SportManagerClient();
BetService.BLOddsControlSettings[] oddsControlSettings = dbSportManager.GetOddsControlSettings("", "");
repositoryOddsControlSettings1.DataSource = oddsControlSettings;
}
And here is code from designer:
//
// repositoryOddsCalculationSettings1
//
this.repositoryOddsCalculationSettings1.AutoHeight = false;
this.repositoryOddsCalculationSettings1.Buttons.AddRange(new DevExpress.XtraEditors.Controls.EditorButton[] {
new DevExpress.XtraEditors.Controls.EditorButton(DevExpress.XtraEditors.Controls.ButtonPredefines.Combo)});
this.repositoryOddsCalculationSettings1.Columns.AddRange(new DevExpress.XtraEditors.Controls.LookUpColumnInfo[] {
new DevExpress.XtraEditors.Controls.LookUpColumnInfo("ID", "ID", 20, DevExpress.Utils.FormatType.None, "", false, DevExpress.Utils.HorzAlignment.Default),
new DevExpress.XtraEditors.Controls.LookUpColumnInfo("Name", "Name")});
this.repositoryOddsCalculationSettings1.DisplayMember = "Name";
this.repositoryOddsCalculationSettings1.Name = "repositoryOddsCalculationSettings1";
this.repositoryOddsCalculationSettings1.NullText = "Select Settings";
this.repositoryOddsCalculationSettings1.PopupSizeable = false;
this.repositoryOddsCalculationSettings1.ValueMember = "ID";
For starters check whether the column name in your Grid datasource and the column in your grid control match. The match is case sensitive so name and Name are not same and hence can cause this issue. Secondly make sure the Grid datasource column datatype matches the value type of the LookUpEdit. If the LookupEdit is returning int and the Grid datasource column datatype is string, this alone can cause lots of headaches.
I would like to set a value to the ComboBox in the DataGridView. I already have changed the comboBoxItems, I just want to select one of them. Thank you in advance!!!
I already solved my problem... I'm gonna post the way I did and hoppefully someone will find this answer too.
dgrDetalle.DataSource = dataTable("select * from yourTable");
DataTable dtCombo = dataTableCombo("select COL_ID DETOC_COL_FK,COL_DESCRIPCION from yourTable2");
string[] strColumns = new string[] { "COL_DESCRIPCION" };
MultiColumnDictionary map = new MultiColumnDictionary(dtCombo, "DETOC_COL_FK", strColumns, 0);
dgrDetalle.Cols["DETOC_COL_FK"].DataMap = map;
As you can see the class that save my life is MultiColumnDictionary.
Note: The combobox items must be loaded in a different DatatTable than the DataTable that is gonna load directly in the grid.
As far as I know, the Comboboxes only actually exist as controls when they are being edited, and therefore don't have a selected item property.
You can simply set the Value property of the cell to the item you want selected, or alternitively, you can set a default value by setting the property:
DataGridViewColumn.DefaultCellStyle.NullValue.
I have a DataGridView with a Binding-Source bound to a Data-Table loaded from an Oracle-Database. (btw. I don't think that the Database-Connection could cause this)
I have also a DataGridViewComboBoxColumn bound to an class of persons (only "has" ID and name), so I can display / allow to edit the name instead of the ID. My problem is now that after the data-binding is completed c# automatically "selects" the first cell of the DGV - see the attached picture.
I also have to use this little piece of code to ensure data integrity:
private void _table_ColumnChanging(object sender, DataColumnChangeEventArgs e)
{
if (e.Column == _table.Columns["NEEDED_ID"])
{
if (e.ProposedValue == null)
{
e.ProposedValue = System.DBNull.Value;
}
}
}
Now using this _table.GetChanges() always returns the first row of the DGV as "modified" but the value isn't really changed - it's only DBNull instead of null. Can I somehow avoid automatic selection of first cell or how to avoid this behavior?
EDIT: Meanwhile I found out that changing the first column to something not editable fixes this problem. But this is nothing more than an workaround. I would really appreciate to get an working solution for this.
EDIT 2: I have also an empty Object 'on top' of the ComboBox-DataSource
DtoPerson blankPerson = new DtoPerson();
blankPerson.Name = String.Empty;
blankPerson.PersonRollenId = -1;
personList.Add(blankPerson);
Try to put a null in your DataGridViewComboBoxColumn's DataSource. example:
SELECT id, description
FROM yourTable
UNION
SELECT NULL, NULL
GridViewName.ClearSelection();
I am new to windows application. I need to add rows in the DataGrid dynamically which has person data. when i do the following is see only the last person in the last row. i see rows populating but with no data. If i do a break on the first fetch i do get the right one. But something is wrong. Any ideas
foreach (var p in personList)
{
gvAdminSummary.Rows.Add(new DataGridViewRow());
gvAdminSummary.Rows[gvAdminSummary.Rows.Count-1].Cells[0].Value = p.FName;
gvAdminSummary.Rows[gvAdminSummary.Rows.Count - 1].Cells[1].Value = p.LName;
gvAdminSummary.Rows[gvAdminSummary.Rows.Count - 1].Cells[2].Value = p.PNo;
}
The DataGridRowView.Add method accepts string arrays:
gvAdminSummary.Rows.Add( { p.FName, p.LName, p.PNo });
Likely, though, there's a better solution for you in binding the grid directly to your person list.
This may not be the right approach. Create a BindingSource and bind a collection of your objects to it. Then bind the BindingSource to the Grid's data source. Make sure your objects implement INotifyPropertyChanged. This way, whenever, you add an object to the collection, or change a property within your object, it'll automatically reflect in the grid.
I don't know about DataGridView, but if you want to stick to inserting data into the control directly, why not use ListView instead? It has an API more suited to your current needs or way of doing things.
Either
gvAdminSummary.Datasource = persons;
gvAdminSummary.databind();
Or
foreach (var p in personList)
{
DataGridViewRow dr = new DataGridViewRow();
dr.cells.add(new datagridcell()) etc.. populate cells
gvAdminSummary.Rows.add(dr);
}
I'm dynamically adding rows to a datagridview this way:
Question question = new Question();
List<Question> questions = question.GetQuestionsByQuestionnaire(questionnaireId);
if (questions != null)
{
dgvQuestions.Columns.Add("Question", "Vraag");
dgvQuestions.Columns.Add("QuestionType", "Vraag type");
dgvQuestions.Columns.Add("Category", "Categorie");
for (int i = 0; i < questions.Count; i++ )
{
int row = dgvQuestions.Rows.Add();
dgvQuestions.Rows[row].Cells["Question"].Value = questions[i].Question;
dgvQuestions.Rows[row].Cells["QuestionType"].Value = questions[i].QuestionType;
dgvQuestions.Rows[row].Cells["Category"].Value = questions[i].Category;
dgvQuestions.Rows[row].Tag = questions[i];
}
}
I don't get any errors, but the cell value stays null and I'm 100% sure that Question, QuestionType and Category contains data. What am i missing here?
I'm not sure about why this is the case, but I'd go for a mix of dynamic data but typed dataset.
What you'd do is:
Create a typed DataSet, add a "Questions" table with the columns you need
Put an instance of your DataSet from the Toolbox on your form (must recompile before that), name it for example myDataSource.
Put a BindingSource on your form, assign the myDataSource to the DataSource property and select your table for the DataMember property.
Assign the binding source to the DataSource property of your DataGridView
Add data to the data source by using for example myDataSource.Questions.NewQuestionsRow() and myDataSource.Questions.AddQuestionsRow(...).
I've just encountered something similar. You might want to make sure EnableViewState is set to True for your GridView.
Make sure VitualMode is set to False for your GridView.