托动旁边的滚动条会触发SCROOL事件,怎样避免他被连续触发?我的问题是在msflexgrid的一列每一个单元格上面放置一个checkbox控件,当通过滚动条移动单元格格时,希望checkbox随着该单元格移动,怎样实现?我是把移动checkbox的代码放在msgrid_Scroll()事件中处理,但是该事件托动一次滚动条会被连续触发很多次,以致出错,怎样处理更好一些?谢谢各位指正,在线急等!!!!

解决方案 »

  1.   

    我也遇到过这个问题,最后干脆用listview了,省事,呵呵
      

  2.   

    一列上只放一个checkbox呢?只有用户单击某一cell时,把checkbox才移到当前cell上,并显示当前行的checkbox状态,在其它操作时把checkbox隐藏。
      

  3.   

    checkbox是一个数组,该列中每一行都有,只要行可见,checkbox状态就必须可见。
      

  4.   

    当滚动的时候你可以判断MSFlexGrid1.TopRow,就得到最顶可见行是哪行了,再显示下面的就可以
      

  5.   

    to: tztz520(午夜逛街) 
    是在scroll事件中处理吗?
    但是scroll会被连续触发,
    在他之前和之后会触发什么事件?
      

  6.   

    Private Sub msGrid_Scroll()
        Dim intRow As Integer
        
        If msGrid.Rows - msGrid.TopRow >= 19 Then
            msGrid.Redraw = False
            For intRow = msGrid.TopRow To msGrid.TopRow + 19
                Check1(intRow - 1).Visible = True
                msGrid.Row = intRow
                Check1(intRow - 1).Move Check1(0).Left, msGrid.Top + msGrid.CellTop + 45
                If intRow = msGrid.TopRow + 19 Then Exit Sub
            Next intRow
            msGrid.Redraw = True
        End If
    End Sub
    这是我的代码,大家帮忙分析一下。
    已经执行完End Sub 程序还会直接跳到for循环去执行,所以总会报错,不可思议!
      

  7.   

    你不用移动checkbox,你所需要的仅仅是知道当前每个checkbox所对应的为哪个单元格就可以了。
    你可以计算出你的msflexgrid的高度,这样你就可以知道整个页面可以显示多少个checkbox,然后在scroll事件中,通过toprow的改变来计算每一行checkbox的值。这样你就不需要移动checkbox,速度却可以提高不少,也可以减少资源的消耗。下面给出一个简单的例子,楼主可以参考参考。Option ExplicitConst HBarHeight = 250
    Const VBarWidth = 250Const CellOffset = 15
    Private mValue() As Long
    Private msngCellHeight As Single
    Private msngCellWidth As Single
    Private msngCellTop As Single
    Private msngCellLeft As SinglePrivate msngHBarOffset As Single
    Private msngVBarOffset As Single
    Private Sub Check1_Click(Index As Integer)
    Dim lngTopCell As Long
        lngTopCell = MSFlexGrid1.TopRow
        mValue(lngTopCell + Index) = Check1(Index).Value
    End SubPrivate Sub Form_Load()
    Dim i As Long
    Dim j As Long
        With MSFlexGrid1
            .Rows = 20
            .Cols = 10
            ReDim mValue(.Rows - 1)
            .HighLight = flexHighlightAlways
            .FocusRect = flexFocusNone
            .ScrollBars = flexScrollBarBoth
            .AllowUserResizing = flexResizeBoth
            .ScrollTrack = True
            msngCellHeight = .CellHeight
            msngCellWidth = .CellWidth
            msngCellTop = .CellTop
            msngCellLeft = .CellLeft
        End With
        For i = 1 To MSFlexGrid1.Rows - 1
            SetCellValue MSFlexGrid1, i, 2, "这是第" & GetFormat(CStr(i)) & "项"
        Next i
    End SubPrivate Sub Form_Resize()
        With MSFlexGrid1
            GetBarOffset
            MSFlexGrid1.Move 0, 0, Me.ScaleWidth, Me.ScaleHeight
            MSFlexGrid1_Scroll
        End With
    End Sub'判断是否有滚动条,并且设置滚动条的宽度或者高度
    Private Sub GetBarOffset()
    Dim lngRows As Long
    Dim lngCols As Long
    Dim sngWidth As Single
    Dim sngHeight As Single
    Dim blnHBar As Boolean
    Dim blnVBar As Boolean    lngRows = MSFlexGrid1.Rows
        lngCols = MSFlexGrid1.Cols
        With MSFlexGrid1
            lngRows = .Rows
            lngCols = .Cols
            '此处最好写一个函数计算每一行的长度
            sngWidth = (msngCellWidth + CellOffset) * lngCols
            '此处最好写一个函数计算每一列的长度
            sngHeight = (msngCellHeight + CellOffset) * lngRows
            
            If sngWidth > .Width Then
                msngHBarOffset = HBarHeight
                sngHeight = sngHeight - HBarHeight
            Else
                msngHBarOffset = 0
            End If
            If sngHeight > .Height Then
                msngVBarOffset = VBarWidth
                sngWidth = sngWidth - VBarWidth
            Else
                msngVBarOffset = 0
            End If
            
            If sngWidth > .Width Then
                msngHBarOffset = HBarHeight
            Else
                msngHBarOffset = 0
            End If
            If sngHeight > .Height Then
                msngVBarOffset = VBarWidth
            Else
                msngVBarOffset = 0
            End If
        End With
    End SubPrivate Sub MSFlexGrid1_Scroll()
        ResetCheckBox
        ShowCheckValue
    End Sub'获得当前显示的行的数量
    Private Function GetShowCount() As Long
    Dim lngRet As Long
        lngRet = (MSFlexGrid1.Height - msngHBarOffset - 15 * 8) / (msngCellHeight + CellOffset) - 1
        If lngRet >= MSFlexGrid1.Rows Then
            lngRet = MSFlexGrid1.Rows - 1
        End If
        GetShowCount = lngRet
    End Function'根据当前的情况设置checkbox
    Private Sub ResetCheckBox()
    Dim lngCount As Long
    Dim lngTopCell As Long
    Dim lngLeftCell As Long
    Dim i As Long
    On Error GoTo ErrHandler
        lngCount = GetShowCount
        lngLeftCell = MSFlexGrid1.LeftCol
        If lngLeftCell > 1 Then
            For i = 0 To Check1.UBound
                Check1(i).Visible = False
            Next i
            Exit Sub
        End If
        If lngCount > Check1.Count Then
            For i = Check1.UBound + 1 To lngCount - 1
                Load Check1(i)
                Check1(i) = mValue(i)
            Next i
        ElseIf lngCount < Check1.Count Then
            For i = Check1.UBound To lngCount - 1 Step -1
                Check1(i).Visible = False
            Next i
        End If
        lngTopCell = MSFlexGrid1.TopRow
        For i = 0 To lngCount - 1
            Check1(i).Move msngCellWidth + 100, msngCellTop + i * (msngCellHeight + CellOffset)
            Check1(i).Visible = True
        Next i
        MSFlexGrid1.ZOrder 1
        Exit Sub
    ErrHandler:
        Err.Clear
    End Sub'设置每一个checkbox的值
    Private Sub ShowCheckValue()
    Dim lngTopCell As Long
    Dim lngCount As Long
    Dim i As Long
        lngTopCell = MSFlexGrid1.TopRow
        lngCount = GetShowCount
        For i = 0 To lngCount - 1
            Check1(i).Value = mValue(lngTopCell + i)
        Next i
    End Sub'设置一个MSHFlexGrid控件的某个单元格
    Private Sub SetCellValue(msfObject As Object, _
                             lngRow As Long, _
                             lngCol As Long, _
                             strValue As String)
       
    Dim lngTmp As Long
       lngTmp = lngRow * msfObject.Cols + lngCol
       msfObject.TextArray(lngTmp) = strValue
    End Sub'获得一个MSHFlexGrid控件的某个单元格
    Private Function GetCellValue(msfObject As Object, _
                                  lngRow As Long, _
                                  lngCol As Long) As String
    Dim lngTmp As Long
       lngTmp = lngRow * msfObject.Cols + lngCol
       GetCellValue = msfObject.TextArray(lngTmp)
    End Function'相当于Format函数
    Private Function GetFormat(ByVal strSource As String, _
                              Optional ByVal strAddChar As String = "0", _
                              Optional ByVal lngTLen As Long = 2, _
                              Optional ByVal blnAddToLeft As Boolean = True) As String
    Dim lngSLen As Long
    Dim strRet As String
    Dim strTmp As String
    Dim i As Long
       lngSLen = Len(strSource)
       If lngSLen >= lngTLen Then
          strTmp = strSource
          GetFormat = strTmp
       ElseIf lngSLen < lngTLen Then
          strTmp = ""
          For i = 1 To lngTLen - lngSLen
             strTmp = strTmp & strAddChar
          Next i
          If blnAddToLeft = True Then
             strRet = strTmp & strSource
          Else
             strRet = strSource & strTmp
          End If
          GetFormat = strRet
       End If
    End Function
      

  8.   

    谢谢yunyu97() 的代码。
    已经解决了,等着接分吧……