bigmacisdn
asked on
Validation of cells in Datagrid
Hi,
I am working on a simple purchase order system in VB.NET 2003
I have a dataset that has a purchase order header (purchtable) and the purchase order lines. (purchlines), joined on purchase Order number.
My form has 2 datagrids.
The top datagrid is connected to purchtable, and shows a list of purchase orders.
The bottom datagrid is connected to purchlines and shows the related lines of the purchase order.
When you click on a purchase order in the top grid, the lines of the purchase order automatically show in the bottom grid.
One of the fields in the purchase order line is an item number (ie Inventory Part number) . (My system has another table of valid items that can be purchased.)
So, when the user keys in an item number, I want to validate the item number against the valid items table. If it is not valid, I want to issue an error message (via msgbox, or .SetColumnError or something)
The solution MUST cover the following situations;
The validation must occur when the user moves off the cell containing the item number. (either via mouse or keyboard) .
If the field is in error, the user must not be able to move to another row in the grid or move the focus to any other part of the form (especially moving to another order by clicking on the order grid). Also the user must not be able to close the form with the item in error.
The cursor should be placed back on the item field in error.
The solution must cover the situation where the users moves to the end of the orderlines grid (creating a new record), and enters an invalid item.
Obviously I can do the actual item # validation code. My question is more about the events (cellchanged, column changing) etc etc. I just can't work it out.
Cheers
Neil Macpherson
I am working on a simple purchase order system in VB.NET 2003
I have a dataset that has a purchase order header (purchtable) and the purchase order lines. (purchlines), joined on purchase Order number.
My form has 2 datagrids.
The top datagrid is connected to purchtable, and shows a list of purchase orders.
The bottom datagrid is connected to purchlines and shows the related lines of the purchase order.
When you click on a purchase order in the top grid, the lines of the purchase order automatically show in the bottom grid.
One of the fields in the purchase order line is an item number (ie Inventory Part number) . (My system has another table of valid items that can be purchased.)
So, when the user keys in an item number, I want to validate the item number against the valid items table. If it is not valid, I want to issue an error message (via msgbox, or .SetColumnError or something)
The solution MUST cover the following situations;
The validation must occur when the user moves off the cell containing the item number. (either via mouse or keyboard) .
If the field is in error, the user must not be able to move to another row in the grid or move the focus to any other part of the form (especially moving to another order by clicking on the order grid). Also the user must not be able to close the form with the item in error.
The cursor should be placed back on the item field in error.
The solution must cover the situation where the users moves to the end of the orderlines grid (creating a new record), and enters an invalid item.
Obviously I can do the actual item # validation code. My question is more about the events (cellchanged, column changing) etc etc. I just can't work it out.
Cheers
Neil Macpherson
ASKER
Thank for your response.
Unfortunately it doesn't help me much as I should have made two things clearer.
There are 1000's of items they can purchase, so any of form of picklist is not viable as it would be too slow and unwieldy.
The user will key the item numbers directly into the orderline, (and they may change the item number on any order line at will) The customer has a 'keyboard centric' approach to the data entry. The item numbers are highly structured and the user can remember them quite easily. It is a fairly high volume/speed data entry environment.
Thus, the validation must be done as the focus leaves the cell.
Unfortunately it doesn't help me much as I should have made two things clearer.
There are 1000's of items they can purchase, so any of form of picklist is not viable as it would be too slow and unwieldy.
The user will key the item numbers directly into the orderline, (and they may change the item number on any order line at will) The customer has a 'keyboard centric' approach to the data entry. The item numbers are highly structured and the user can remember them quite easily. It is a fairly high volume/speed data entry environment.
Thus, the validation must be done as the focus leaves the cell.
Hi
Yeah i see your solution-architecture ,needs some consideration.
Speed is the need here -:)
1) In my opinion ,working with disconected dataset is very adviseble (once it is populated ,the responce time is not be negotiated)
2) Consider that performance is 4x faster with typed(XSD) than untyped datasets (some say(though it is argued)) but in my opinon they are faster.
<<When you click on a purchase order in the top grid, the lines of the purchase order automatically show in the bottom grid.
<<One of the fields in the purchase order line is an item number (ie Inventory Part number)
But your idea with the validation issue (hmmm .. take another approach into consideration !) eighter there is such item or not(look up in the table),
in this case i would make a contextmenu availeble in bottum grid ["when purchase order line grid has focus"] (mouse right click or letter-key shortcut) E -for edit the item/ D- for deleting an item A- for adding an item ! Then popup one of 3 forms depending on user choice and handle it from there
1) if E is pressed(or clicked in contxtmenu) then popup the edit form and take the selected row data from purchlines.Grid with you (usually here it would bee an
amount issue handling)
2) if A is pressed(or clicked in contxtmenu) do as mentioned above(1) and let the user type an item number that you would look up in the table to see wether it
exist's or not ( if true ! show the item data in some labels or what ever - then enable an add button and validate the amount to purchase)
(and that it is an integer)
3) as in 1,2 for deleting handling(primary key from the purchlines.Grid row (data) would be the one to delete
This way you'll have a friendly user interaction and in my opinion ??? more easy for the user to learn and implement.
Well it can be that i still have misunderstood the algorithm you are asking ,but this way it speeds responce time while only handling specific rows.
if you want some code to lookup rows in a dataset by primary keys or a select() + the usual crud methods then let know
well i know that this is not what you are asking for but hope you can see my point
vbturbo
Yeah i see your solution-architecture ,needs some consideration.
Speed is the need here -:)
1) In my opinion ,working with disconected dataset is very adviseble (once it is populated ,the responce time is not be negotiated)
2) Consider that performance is 4x faster with typed(XSD) than untyped datasets (some say(though it is argued)) but in my opinon they are faster.
<<When you click on a purchase order in the top grid, the lines of the purchase order automatically show in the bottom grid.
<<One of the fields in the purchase order line is an item number (ie Inventory Part number)
But your idea with the validation issue (hmmm .. take another approach into consideration !) eighter there is such item or not(look up in the table),
in this case i would make a contextmenu availeble in bottum grid ["when purchase order line grid has focus"] (mouse right click or letter-key shortcut) E -for edit the item/ D- for deleting an item A- for adding an item ! Then popup one of 3 forms depending on user choice and handle it from there
1) if E is pressed(or clicked in contxtmenu) then popup the edit form and take the selected row data from purchlines.Grid with you (usually here it would bee an
amount issue handling)
2) if A is pressed(or clicked in contxtmenu) do as mentioned above(1) and let the user type an item number that you would look up in the table to see wether it
exist's or not ( if true ! show the item data in some labels or what ever - then enable an add button and validate the amount to purchase)
(and that it is an integer)
3) as in 1,2 for deleting handling(primary key from the purchlines.Grid row (data) would be the one to delete
This way you'll have a friendly user interaction and in my opinion ??? more easy for the user to learn and implement.
Well it can be that i still have misunderstood the algorithm you are asking ,but this way it speeds responce time while only handling specific rows.
if you want some code to lookup rows in a dataset by primary keys or a select() + the usual crud methods then let know
well i know that this is not what you are asking for but hope you can see my point
vbturbo
Also it would save validation routines when the user for example moves down along the rows and each rows item number needs to be validated
before the next one can be selected..
before the next one can be selected..
Well
here one approach dealing with cell validation if you are determined to stick with your preliminary approach
download the 5.20 example solution
http://www.syncfusion.com/FAQ/WindowsForms/FAQ_c44c.aspx#q773q
vturbo
here one approach dealing with cell validation if you are determined to stick with your preliminary approach
download the 5.20 example solution
http://www.syncfusion.com/FAQ/WindowsForms/FAQ_c44c.aspx#q773q
vturbo
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Hi Guys,
Sorry to not respond. I have been on vacation.
I actually solved it myself, as shown in the following generalised code snippet.
AddHandler DatasetPurchaseOrders1.Tab les("Order lines").Co lumnChangi ng, AddressOf Column_Changing
Private Sub Column_Changing(ByVal sender As Object, ByVal e As System.Data.DataColumnChan geEventArg s)
Dim CurrentCell As String
e.Row.ClearErrors()
' validate certain columns
If (e.Column.ColumnName.Equal s("Item")) Then
CurrentCell = CType(e.ProposedValue, String)
If (CurrrentCell = "invalid value") Then
MessageBox.Show("Value " + Trim(CurrentCell) + " is invalid.")
' put the old value back
e.ProposedValue = e.Row(e.Column.ColumnName)
' signal row in error
e.Row.RowError = "Value " + Trim(CurrentCell) + " is invalid."
e.Row.SetColumnError(e.Col umn, "Item error")
end if
end if
But I would like to award all points to VBTURBO
Cheers
Neil
Sorry to not respond. I have been on vacation.
I actually solved it myself, as shown in the following generalised code snippet.
AddHandler DatasetPurchaseOrders1.Tab
Private Sub Column_Changing(ByVal sender As Object, ByVal e As System.Data.DataColumnChan
Dim CurrentCell As String
e.Row.ClearErrors()
' validate certain columns
If (e.Column.ColumnName.Equal
CurrentCell = CType(e.ProposedValue, String)
If (CurrrentCell = "invalid value") Then
MessageBox.Show("Value " + Trim(CurrentCell) + " is invalid.")
' put the old value back
e.ProposedValue = e.Row(e.Column.ColumnName)
' signal row in error
e.Row.RowError = "Value " + Trim(CurrentCell) + " is invalid."
e.Row.SetColumnError(e.Col
end if
end if
But I would like to award all points to VBTURBO
Cheers
Neil
here is an approach that could cover the algorithm you are asking for.
A sort of sales line item (bussines rule)
1) populate your top grid with items to sell ,where user can pick from.
2) make a validation rule (in this case a row filter to the grid) so that the user is forced to filter out and pick an item before it can be entered in the bottum grid.
that way you eliminate the IF (item number is valid) because of the picked(clicked) row in the top grid.
3) have an amount textbox where user can enter an amount to sell.
4) when entering a item in bottum grid validate check if validation rules are meet and add a new row in the dataset's table purchline if true.
show entered items in bottum grid
nb. an enterkey_press when user moves up / down in the grid can easily be implemented to.
Imports System.Data.OleDb
Imports System.Windows.Forms.DataG
Imports System.Windows.Forms.DataG
Dim sStrVal as Boolean=False
Dim oDatarow As DataRow
Private Const TABLE_NAME As Object = "purchtable"
'declare your dataset.....etc.
'handle the picked out item, and set the first val rule to true
Private Sub DataGrid1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.Mouse
Windows.Forms.Cursor.Curre
Dim DataGrid1 As DataGrid = CType(sender, DataGrid)
Dim hti As System.Windows.Forms.DataG
hti = DataGrid1.HitTest(e.X, e.Y)
Try
lbl_item_id.Text = DataGrid1(hti.Row, 0).ToString()
lbl_item_desc.Text = DataGrid1(hti.Row, 1).ToString()
lbl_item_price.Text = DataGrid1(hti.Row, 2).ToString()
'set sStrVal to true because it exsist's
sStrVal=true
Catch '//empty catch .. do nothing
End Try
amount_to_sell.Text = ""
End Sub
'filter on the items_id's in Datagrid1, maybee add one more txtfilter to be able to search for item_descriptions also
Private Sub txtFilter_TextChanged(ByVa
With dataset.Tables(TABLE_NAME)
.DefaultView.RowFilter = "items_id like '" & txtFilter.Text & "%'"
DataGrid1.DataSource = .DefaultView
End With
End Sub
' enter the picked item into bottum grid
Private Sub Enteritem_in_Datagrid2()
If sStrVal=False Then
MsgBox("Missing information : " & vbCrLf & _
"Chose a Product ?", MsgBoxStyle.Information Or _
MsgBoxStyle.Question Or MsgBoxStyle.DefaultButton1
Exit Sub
End If
If amount_to_sell.Text = "" Then
MsgBox("Missing information : " & vbCrLf & _
"Please enter no. of items to purchase !", MsgBoxStyle.Information Or _
MsgBoxStyle.Question Or MsgBoxStyle.DefaultButton1
Exit Sub
End If
' add the purchased item into purchlines table in your dataset table "purchline"
oDatarow = dataset.Tables("purchlines
oDatarow.Item(0) = lbl_item_id.Text
oDatarow.Item(1) = lbl_item_desc.Text
oDatarow.Item(2) = lbl_item_price.Text
dataset.Tables("purchlines
Datagrid2.Datasource=datas
End Sub
' set some grid properties and collum width's
Private Sub SetTableStyleItemsGrid()
Dim grdTableStyle1 As New DataGridTableStyle
grdTableStyle1.MappingName
grdTableStyle1.RowHeadersV
grdTableStyle1.HeaderBackC
grdTableStyle1.HeaderBackC
grdTableStyle1.HeaderForeC
grdTableStyle1.GridLineCol
grdTableStyle1.BackColor = Color.LightSteelBlue
DataGrid1.BackgroundColor = Color.White ';
Dim Data1 As New DataGridTextBoxColumn
Data1.MappingName = "item_id"
Data1.HeaderText = "ID"
Data1.Width = 20
grdTableStyle1.GridColumnS
Dim Data2 As New DataGridTextBoxColumn
Data2.MappingName = "item_desc "
Data2.HeaderText = "Product name."
Data2.Width = 120
grdTableStyle1.GridColumnS
Dim Data3 As New DataGridTextBoxColumn
Data3.MappingName = "item_price"
Data3.HeaderText = "Price"
Data3.Width = 60
grdTableStyle1.GridColumnS
DataGrid1.TableStyles.Add(
End Sub
hope you can use some of it
vbturbo