Level Extreme platform
Subscription
Corporate profile
Products & Services
Support
Legal
Français
DragDrop in Grid
Message
From
07/08/2003 08:58:27
Cetin Basoz
Engineerica Inc.
Izmir, Turkey
 
 
To
06/08/2003 23:20:42
General information
Forum:
Visual FoxPro
Category:
Coding, syntax & commands
Miscellaneous
Thread ID:
00817557
Message ID:
00817665
Views:
40
This message has been marked as the solution to the initial question of the thread.
>Hi All,
>
>I have a Grid in VFP 7 whose recordsource is a cursor.
>
>My challenge is to allow users to change the row order (ie move the rows) via dragdrop.
>
>My original intention was that in the Mousedown event of the controls in the grid (textbox, spinner, combobox etc) to populate a form property with the X Y coordinates of the mouse and then in the mouse move event test if the mouse has moved by a set number of pixels before calling Drag(1). My problem to date is where to test and call the drag() event. The grids mousemove event doesn't appear to fire and the texbox's mousemove event doesn't fire if you move to another row or so it seems to me. Can anyone give me pointers.
>
>I also have other code in the controls mousedown event that takes care of allowing the user to select multiple rows.
>
>Any help greatly appreciated.

David,
I prefer MouseDown to start the drag (Grid has a hierarchy. MouseMove fires for the active textbox object first then column's as you move to another row/col).
In sample code below there are 2 subclasses of one main grid class. Diffence between them one uses DragDrop and other DragOver (with DragDrop row order doesn't change till a drop).
In sample form it's not intended to do a DD between the grids (though works), just a sample of doing that in 2 different ways.
oForm = Createobject('myForm')
oForm.Show
Read Events

Define Class myForm As Form
  DataSession = 2
  Width = 450
  Height = 540

  Procedure Init
    This.Newobject('myGrid1','mySorterGrid1','','','crsTest')
    This.Newobject('myGrid2','mySorterGrid2','','','crsTest')
    With This.myGrid1
      .Top = 10
      .Left = 25
      .Width = 400
      .Height = 250
      .Visible = .T.
    Endwith
    With This.myGrid2
      .Top = 280
      .Left = 25
      .Width = 400
      .Height = 250
      .Visible = .T.
    Endwith
  Endproc

  Procedure Load
    Select  cust_id, company,contact, ;
      0x7FFFFFFF As sorter, 0x7FFFFFFF As original ;
      from customer ;
      order By cust_id ;
      into Cursor crsTest ;
      readwrite
    Replace All sorter With Recno(), original With Recno()
    Index On sorter Tag sorter
  Endproc

  Procedure QueryUnload
    Clear Events
  Endproc
Enddefine

Define Class myGrid As Grid
  DeleteMark = .F.
  ReadOnly = .T.
  RecordMark = .F.
  ScrollBars = 3
  SplitBar = .F.
  Highlight = .F.
  HighlightRow = .F.
  Name = "grdMyGrid"

  Procedure AddColumn
    Lparameters nIndex, cAlias, cField
    Nodefault
    This.AddObject("clm"+cField,"myColumn", cAlias+"."+cField,nIndex)
  Endproc

  Procedure Init
    Lparameters tcRecordsource
    With This
      .ColumnCount = -1
      .RecordSource = tcRecordsource
      nOldColCount = .ColumnCount
      For ix = 1 To Fcount(tcRecordsource)
        .AddColumn(ix, tcRecordsource,Field(ix,tcRecordsource))
      Endfor
      .ColumnCount = nOldColCount
    Endwith
  Endproc

  Procedure MyDragDrop
    Lparameters oSource, nXCoord, nYCoord, nState
    Local lnFrom, lnTo
    With This
      nXCoord_In = Mcol(Wontop(),3)
      nYCoord_In = Mrow(Wontop(),3)
      Store 0 To nWhere_Out , nRelRow_Out , nRelCol_Out , nView_Out
      If .GridHitTest(nXCoord_In, nYCoord_In, ;
          @nWhere_Out, @nRelRow_Out, @nRelCol_Out) And nWhere_Out = 3
        lnFrom = Recno()
        .ActivateCell(nRelRow_Out, nRelCol_Out)
        lnTo = Recno()
        .MoveRecord(lnFrom,lnTo)
      Endif
    Endwith
  EndProc
  
  Procedure MoveRecord
    Lparameters tnFrom, tnTo
    If tnFrom = tnTo
      Return
    Endif
    Local lnFrom, lnTo
    Select (This.RecordSource)
    Go tnTo
    lnTo = sorter
    Go tnFrom
    lnFrom = sorter
    If lnTo < lnFrom
      Replace sorter With sorter+1 For Between(sorter,lnTo,lnFrom-1)
    Else
      Replace sorter With sorter-1 For Between(sorter,lnFrom+1,lnTo)
    Endif
    Go tnFrom
    Replace sorter With lnTo
    This.Refresh
  Endproc
Enddefine

Define Class mySorterGrid1 As myGrid
  Name = "grdMyGrid"

  Procedure DragDrop
    Lparameters oSource, nXCoord, nYCoord, nState
    this.MyDragDrop(oSource, nXCoord, nYCoord, nState)
  Endproc
Enddefine

Define Class mySorterGrid2 As myGrid
  Name = "grdMyGrid"

  Procedure DragOver
    Lparameters oSource, nXCoord, nYCoord, nState
    this.MyDragDrop(oSource, nXCoord, nYCoord, nState)
  Endproc
Enddefine

Define Class myColumn As Column
  Resizable = .F.
  Movable = .F.
  Procedure Init
    Lparameters cControlSource, nIndex
    With This
      .ControlSource = cControlSource
      .ColumnOrder = nIndex
      .AddObject("myText","myGridTxtBox")
      .CurrentControl = "myText"
      .Sparse = .F.
    Endwith
  Endproc
Enddefine

Define Class myGridTxtBox As TextBox
  Name = "Text1"
  BorderStyle = 0

  Procedure MouseDown
    Lparameters nButton, nShift, nXCoord, nYCoord
    If nButton=1
      nStart=Seconds()
      Do While Mdown() And Seconds() - nStart < 1
        If Seconds() - nStart > 0.8
          This.Drag(1)
          Exit
        Endif
      Enddo
    Endif
  Endproc
Enddefine
PS: If your intention on multiselect is kind of fast moverlist you might want to check FoxyClasses. It has a MoverListxx class and a MultiselectGrid class as well (enhanced version of infamous MultiselectGrid - also supports checkboxes via chkBoxes property).
Cetin
Çetin Basöz

The way to Go
Flutter - For mobile, web and desktop.
World's most advanced open source relational database.
.Net for foxheads - Blog (main)
FoxSharp - Blog (mirror)
Welcome to FoxyClasses

LinqPad - C#,VB,F#,SQL,eSQL ... scratchpad
Previous
Reply
Map
View

Click here to load this message in the networking platform