Monday, November 28, 2011

Enumerators in datagridviews - careful

Wrote some code that was doing some copying of rows in datagridviews based on what the user had selected.
I should have seen this one coming, but the selected rows changes out from under you if you write code like this:

For each SelectedRow as DataGridViewRow in dgvSource.SelectedRows
  dgvSource.Rows.Add(NewRowBasedOnSelectedRow)
Next

As soon as you add the row, the selected rows property gets reset.
I actually trapped the selection changing. It goes from what is was, to 0, to 1.

The workaround was simple - build a second list of rows to process before I start adding to the source
The annoying this is if you do this kind of thing with a list, you get an exception thrown because the enumerator fails. The datagridview must be trapping the exception.


Getting autonumber/identity fields after row add oledb

Adding a row to a table where autonumber is set on the field means you don't know the autonumber field contents until after the row has actually been added. This is problematic when you're doing some referential integrity in oledb.

To determine the autonumber field contents, execute the following just after the row is added

Dim cmdNewID As New OleDbCommand("SELECT @@IDENTITY", TheOledbDataConnection)

Dim NewTakeoffId as Integer = cmdNewID.ExecuteScalar

Friday, November 18, 2011

Finding absolute position of a control on a windows form

I wanted to overlay a datagridview with a dropdown depending on certain conditions, so using a datagridview combo box which does it always didnt work

So I had the bright idea of creating a combobox on the fly, and I wanted it to land right on the cell.
The trick was the cell is in a datagrid, and the datagrid is nested in some panels

So I had to find out where I was from the base of the form.
This code does that

Private Function GetPositionInForm(ByVal ctrl As Control) As Point
        Dim P As Point = ctrl.Location
        Dim Parent As Control = ctrl.Parent
        While Parent.Name <> ctrl.FindForm.Name
            P.Offset(Parent.Location.X, Parent.Location.Y)
            Parent = Parent.Parent
        End While
        Return P
    End Function

When using it in a grid, you need the final touch of the row and cell position

Dim NewPosition As Point = GetPositionInForm(dgvSourceTakeoff)
Dim CellRectangle As Rectangle = grid.GetCellDisplayRectangle(col,row,True)
NewPosition.X += CellRectangle.Location.X
NewPosition.Y += CellRectangle.Location.Y
cboSelector.Location = NewPosition

First post

So I keep learning all sorts of technical lessons that I don't want to lose

I finally had the bright idea of blogging them.

That way I won't lose them, and maybe someone else will find them useful

And away we go (I miss you Ed and Johnny)