Ask the MultiValued Visual Basic Expert - #1

(as published in Spectrum magazine - Nov/Dec 96)

** updated Jun. 19, 1997 **
To email your questions to "Ask the MultiValued VB Expert", click here.
Copyright © 1996-97 Caduceus Consulting. All rights reserved.

Using the Grid Control to edit multivalues

I want to edit the contents of a multi-valued string that I have brought into VB from my Pick-type host, but VB’s Grid control seems to be limited to display only. What is the best way to edit multi-values, especially across more than one attribute? - W. Campbell, Intellidata Inc.

You are indeed correct that the Grid control that comes with the Professional edition of Visual Basic has its limitations. However it is possible to do what you are looking for, without adding other custom controls. This solution will use the Grid control to display the values and a moving TextBox to edit them. [A sophisticated version of this solution code is now downloadable from this site!] First, make sure that there are enough columns and rows to accommodate all of the attributes and values. Then load the values into the Grid control. There are two ways to do this: (a) one value at a time, using the following code:

Grid1.Row = AttrNum%
Grid1.Col = ValueNum%
Grid1 = MultiValue$

or (b) all at once by converting (either on the MultiValue host or in VB) all value marks (ASCII 253) to tabs (ASCII 9) and all attribute marks (ASCII 254) to CR’s (ASCII 13) and then using this code:

Grid1.SelStartRow = 1
Grid1.SelEndRow = NumAttrs%
Grid1.SelStartCol = 1
Grid1.SelEndCol = MaxNumVals%
Grid1.Clip = ConvertedItem$

Set the BorderStyle property of the TextBox control to 0 (none), the Visible property to False, and the Appearance property (for VB version 4 users) to 0 (flat). Next, add the code shown below to the specified event subroutines. Now you can click on any cell and edit the contents directly. Note that the standard VB Grid control has a limit of 255 characters per cell (or in this case, per value).

Sub Text1_Change()
. . Grid1 = Text1
End Sub
 
 
Sub Grid1_MouseDown(Button As Integer, Shift As Integer, X As _
. . . . . . . . . . . . . . . . . . . . . . Single,Y As Single)
. . MoveTextBox Text1, Grid1
. . With Text1
. . . . .Height = Grid1.RowHeight(Grid1.Row) - 30
. . . . .Width = Grid1.ColWidth(Grid1.Col) - 30
. . . . .Text = Grid1 .SelStart = 0 '< these 2 lines highlight
. . . . .SelLength = Len(Text1) '< the current text
. . End With
. . Text1.SetFocus
End Sub
 

Sub MoveTextBox(TBox As TextBox, Grd As Grid)
With Grd
. . If .ColIsVisible(.Col) And .RowIsVisible(.Row) Then
. . . . TBox.Visible = True
. . Else
. . . . ' allow focus retention but make invisible...
. . . . TBox.Left = -50 - TBox.Width
. . . . Exit Sub
. . End If
. . TBox.Left = .Left + .ColPos(.Col) + Screen.TwipsPerPixelX
. . TBox.Top = .Top + .RowPos(.Row) + Screen.TwipsPerPixelY
. . ' Note: do not use TwipsPerPixel adjustment for combo boxes
End With
End Sub

If the Grid cannot show all of the values at once (ie. has scroll bars), then you should add a Timer control with an Interval property set to 100, and the following code:

Sub Timer1_Timer()
Static LastLeft As Integer, LastTop As Integer
With Grid1
. . If (LastLeft <> .LeftCol) Or (LastTop <> .TopRow) Then
. . . . LastLeft = .LeftCol
. . . . LastTop = .TopRow
. . . . MoveTextBox Text1, Grid1
. . End If
End With
End Sub

[A sophisticated version of this solution code is now downloadable from this site!]
To email your questions to "Ask the MultiValued VB Expert", click here.
Copyright © 1996-97 Caduceus Consulting. All rights reserved.
Revised: June 19, 1997.

Return to Caduceus Consulting Home Page

Copyright © 2006 intellact
Last modified: Thursday May 25, 2006