DataGridView: Finding a row in code
-
2012년 7월 25일 수요일 오전 12:28
Visual Studio 2010 Pro
SQL Server 2008 back end
Using a Master/Detail form and bound datagridviews
I am trying to "Find" a certain row if it exists in the DETAIL grid, witch is bound to a FOREIGN KEY in my dataset.
This:
int i = fKPurchaseOrderDetailPurchaseOrderBindingSource.Find("Production_No", myProdNo); if (i > -1) { fKPurchaseOrderDetailPurchaseOrderBindingSource.CurrencyManager.Position = i; }gives me THIS error:
DataMember property 'Production_No' cannot be found on the DataSource.
Here is a snap of my Dataset
So tell me... what am I doing wrong?
Just for debugging, How do I get a list of what CAN be "found on the datasource"?
I'd rather live with false hope than with false despair.
- 편집됨 Bryan Valencia 2012년 7월 25일 수요일 오전 12:35 added detail
모든 응답
-
2012년 7월 25일 수요일 오전 7:48
Hi, you were not precise, or do you wanna find a DataGridViewRow, or some value inside the row (the value of Product_No column)?
But based on your code, you are trying to do something completely different.
Give us more info, and please use some more.
--
But Find method seem to be Ok.
Mitja
-
2012년 7월 25일 수요일 오전 7:57
You know, you try to be precise and somehow there is always room for improvement.
I want to find the detail grid row that contains the production number that I have already collected in a search (that's the variable myProdNo). Once I find the row, I'd like to move the cursor there (or maybe set the grid row background to a different color).
I'd rather live with false hope than with false despair.
-
2012년 7월 25일 수요일 오전 8:10
Tell me, what if your DataSource type? Is it DataTable?
But in any case, i would suggest you to do this with a different approach. Personally I would not use Find() method what so ever, but rather to do a loop over the dataGridView it self, and check that "Product_No" column. And if the number would be find (maybe even more of them in multiple rows), that/those row(s) would be selected (or colored differently).
This is my suggestion:
int myProdNo = 1; //some number you are looking for! int tempNo = 0; foreach(DataGridViewRow row in dataGridView1.Rows) { if(!row.IsNewRow) { tempNo = int.Parse(row.Cells["ProductNo"].Value.ToString()); if(tempNo == myProdNo) { row.DefaultCellStyle.BackColor = Color.Black; //or any other color! } } }
NOTE: I hope you have the "Product_No" column inisde datagridview control!
Mitja
-
2012년 7월 25일 수요일 오후 9:42
Actually if it's just the cell color, I was able to do this...
private void OrderDetailsGrid_RowPrePaint(object sender, DataGridViewRowPrePaintEventArgs e) { if (OrderDetailsGrid.Rows[e.RowIndex].Cells["DetailProductionNo"].Value.ToString() == myProdNo) { OrderDetailsGrid.Rows[e.RowIndex].DefaultCellStyle.Font = new System.Drawing.Font(OrderDetailsGrid.Font, System.Drawing.FontStyle.Bold); } }I'd rather live with false hope than with false despair.
-
2012년 7월 27일 금요일 오전 7:22중재자
Hi Bryan,
You can search for the item by using property descriptor instead of the property name, so you can avoid the can't found DataMember property error.
Try the code below.
var v = fKPurchaseOrderDetailPurchaseOrderBindingSource.CurrencyManager.GetItemProperties(); var vv = this.fKPurchaseOrderDetailPurchaseOrderBindingSource.Find(v["Production_No"], myProdNo);
Best Regards,
Bob Wu [MSFT]
MSDN Community Support | Feedback to us
-
2012년 7월 27일 금요일 오후 6:58Nope. it just gives a "capability not supported" error.
I'd rather live with false hope than with false despair.
-
2012년 7월 28일 토요일 오전 6:09
Hello, here is a thought. The code below works against a strong type DataSet using Microsoft NorthWind database, Categories table. All objects below, BindingSource and DataSet where dropped onto the form.
In Form Load event
Me.CategoriesTableAdapter.Fill(Me.NORTHWNDDataSet.Categories)
For the search I use a hard coded variable, you already have a method I am guessing to get the ID to search with. If there where a chance the ID did not exists in the detail table you would check the result before setting the BindingSource Position. FindByCategoryID is a method (function) generated by Visual Studio.
Dim KeyToFind As Integer = 4 CategoriesBindingSource.Position = NORTHWNDDataSet.Categories.FindByCategoryID(KeyToFind).CategoryID - 1
If the Find method does not exists we could position via the language extension below against the DataGridView which has a Bindingsource (same as above) that when setting the current cell positions the DataGridView which you can detect in the PositionChanged event of the BindingSource.
Usage, argument 1 is the DataGridView ColumnName to search on, argument 2 is the value to find, argument 3 indicates a full or partial search. The last argument was tossed in to show you can get the row selected cell values.
Dim Row As New DataGridViewRow If DataGridView1.Seek("CategoryNameDataGridViewTextBoxColumn", "Confections", False, Row) Then Console.WriteLine("[{0}]", Row.Cells(0).Value) End IfThe extension needs to be in a code module, not a class or the form.
<System.Diagnostics.DebuggerStepThrough()> _ <Runtime.CompilerServices.Extension()> _ Public Function Seek(ByVal sender As DataGridView, ByVal ColumnName As String, ByVal Value As String, ByVal Part As Boolean, ByRef Row As DataGridViewRow) As Boolean Dim Located As Boolean = False If sender.Columns.Contains(ColumnName) Then If Part Then Row = (From Rows In sender.Rows.Cast(Of DataGridViewRow)() Where Rows.Cells(ColumnName).Value.ToString().ToUpper.Contains(Value.ToUpper)).FirstOrDefault Else Row = (From Rows In sender.Rows.Cast(Of DataGridViewRow)() Where Rows.Cells(ColumnName).Value.ToString().ToUpper = Value.ToUpper).FirstOrDefault End If If Not IsNothing(Row) Then If sender.CurrentCell.RowIndex <> Row.Index Then sender.CurrentCell = sender(0, Row.Index) End If Located = True End If Return Located Else Throw New Exception("Column '" & ColumnName & "' not contained in this DataGridView") End If End FunctionAlternate still using the above we can get data from the current row in the BindingSource by casting it as an DataRowView. In this case the last argument of the Seek method is not needed and the extension would be as below
Dim Row As New DataGridViewRow If DataGridView1.Seek("CategoryNameDataGridViewTextBoxColumn", "Confections", False, Row) Then Console.WriteLine(CType(CategoriesBindingSource.Current, DataRowView).Item("Categoryid").ToString) End IfModified
If DataGridView1.Seek("CategoryNameDataGridViewTextBoxColumn", "Confections", False) Then Console.WriteLine(CType(CategoriesBindingSource.Current, DataRowView).Item("Categoryid").ToString) End If<System.Diagnostics.DebuggerStepThrough()> _ <Runtime.CompilerServices.Extension()> _ Public Function Seek(ByVal sender As DataGridView, ByVal ColumnName As String, ByVal Value As String, ByVal Part As Boolean) As Boolean Dim Row As New DataGridViewRow Dim Located As Boolean = False If sender.Columns.Contains(ColumnName) Then If Part Then Row = (From Rows In sender.Rows.Cast(Of DataGridViewRow)() Where Rows.Cells(ColumnName).Value.ToString().ToUpper.Contains(Value.ToUpper)).FirstOrDefault Else Row = (From Rows In sender.Rows.Cast(Of DataGridViewRow)() Where Rows.Cells(ColumnName).Value.ToString().ToUpper = Value.ToUpper).FirstOrDefault End If If Not IsNothing(Row) Then If sender.CurrentCell.RowIndex <> Row.Index Then sender.CurrentCell = sender(0, Row.Index) End If Located = True End If Return Located Else Throw New Exception("Column '" & ColumnName & "' not contained in this DataGridView") End If End Function
KSG
-
2012년 7월 28일 토요일 오후 4:26
Well I'll have to translate all this into C#, but I get the drift.
It seems needlessly complicated for what should be included functionality. I am becoming more and more unimpressed with the DatagridView.
I'd rather live with false hope than with false despair.
-
2012년 7월 28일 토요일 오후 6:38
Well I'll have to translate all this into C#, but I get the drift.
It seems needlessly complicated for what should be included functionality. I am becoming more and more unimpressed with the DatagridView.
I'd rather live with false hope than with false despair.
I will not address being unimpressed with the DataGridView other than saying I have always found a solution for my needs. In regards to It seems needlessly complicated you can slim down the code.
Keeping with using the code as a language extension
if (DataGridView1.Seek("CategoryNameDataGridViewTextBoxColumn", "Confections")) { Console.WriteLine(((DataRowView)CategoriesBindingSource.Current)["Categoryid"].ToString()); }
[System.Diagnostics.DebuggerStepThrough(), Runtime.CompilerServices.Extension()] public bool Seek(DataGridView sender, string ColumnName, string Value) { bool Located = false; var Row = ( from Rows in sender.Rows.Cast<DataGridViewRow>() where Rows.Cells(ColumnName).Value.ToString().ToUpper() == Value.ToUpper()).FirstOrDefault select Rows; if (Row != null) { sender.CurrentCell = sender[0, Row.Index]; Located = true; } return Located; }Lets say you know at least one row exists
DataGridView1.CurrentCell = DataGridView1(0, ( from Rows in DataGridView1.Rows.Cast<DataGridViewRow>() where Rows.Cells("CategoryNameDataGridViewTextBoxColumn").Value.ToString().ToUpper() == ValueToFind).FirstOrDefault.Index) select Rows;KSG
- 답변으로 표시됨 Bob Wu-MTMicrosoft Contingent Staff, Moderator 2012년 8월 9일 목요일 오전 8:37
-
2012년 7월 31일 화요일 오전 10:48중재자
Nope. it just gives a "capability not supported" error.
I'd rather live with false hope than with false despair.
Hi Bryan,
My solution works great on my side and I'm not sure what is going on on your side.
Could you please tell me which line throw the error message and post both the code and exact error message here?
Could you please tell us more details about your application, such as the way you set the datasource and where the data come from?
Anyway, here is my sample, you should check it out.
Best Regards,
Bob Wu [MSFT]
MSDN Community Support | Feedback to us
- 답변으로 표시됨 Bob Wu-MTMicrosoft Contingent Staff, Moderator 2012년 8월 9일 목요일 오전 8:37

