zoukankan      html  css  js  c++  java
  • (VB.net)自定义TableLayoutPanel使它能够在运行时用鼠标改变行高和列宽。

    喜欢看C#的童鞋,这里有个工具,你们可以自己转换:http://converter.telerik.com/

    想达到这个效果,首先新建一个新的项目。在项目名字上面右击,新增一个类,类名为:TableLayoutPanelEx.vb。 然后只要复制下面的代码到类中即可。

    Public Class TableLayoutPanelEx
        Inherits TableLayoutPanel
    
        Private Const WM_NCHITTEST As Integer = &H84
        Private Const WM_MOUSEMOVE As Integer = &H200
        Private Const WM_LBUTTONDOWN As Integer = &H201
        Private Const WM_LBUTTONUP As Integer = &H202
        Private Const MK_LBUTTON As Integer = &H1
    
        Private VBorders As New List(Of Integer)
        Private HBorders As New List(Of Integer)
        Private selColumn As Integer = -1
        Private selRow As Integer = -1
    
        Public Sub New()
            Me.DoubleBuffered = True
            Me.CellBorderStyle = TableLayoutPanelCellBorderStyle.Single
        End Sub
    
        Protected Overrides Sub OnHandleCreated(ByVal e As System.EventArgs)
            MyBase.OnHandleCreated(e)
            If Not Me.DesignMode Then ResetSizeAndSizeTypes()
        End Sub
    
        Public Shadows Property ColumnCount() As Integer
            Get
                Return MyBase.ColumnCount
            End Get
            Set(ByVal value As Integer)
                MyBase.ColumnCount = value
                If Me.Created And Not Me.DesignMode Then ResetSizeAndSizeTypes()
            End Set
        End Property
    
        Public Shadows Property RowCount() As Integer
            Get
                Return MyBase.RowCount
            End Get
            Set(ByVal value As Integer)
                MyBase.RowCount = value
                If Me.Created And Not Me.DesignMode Then ResetSizeAndSizeTypes()
            End Set
        End Property
    
        Public Sub ResetSizeAndSizeTypes()
            Dim cW As Single = CSng((Me.ClientSize.Width  Me.GetColumnWidths.Length) - 1)
            For c As Integer = 0 To Me.GetColumnWidths.Length - 1
                Me.ColumnStyles(c).SizeType = SizeType.Absolute
                Me.ColumnStyles(c).Width = cW
            Next
    
            Dim cH As Single = CSng((Me.ClientSize.Height  Me.GetRowHeights.Length) - 1)
            For r As Integer = 0 To Me.GetRowHeights.Length - 1
                Me.RowStyles(r).SizeType = SizeType.Absolute
                Me.RowStyles(r).Height = cH
            Next
        End Sub
    
        Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
            MyBase.WndProc(m)
            If Me.Created And Not Me.Disposing Then
                If m.Msg = WM_NCHITTEST Then
                    Dim loc As Point = Me.PointToClient(MousePosition)
                    VBorders.Clear()
                    HBorders.Clear()
                    If Me.ColumnCount > 1 Then
                        For w As Integer = 0 To Me.GetColumnWidths.Length - 2
                            If w = 0 Then
                                VBorders.Add(Me.GetColumnWidths(w))
                            Else
                                VBorders.Add(VBorders(VBorders.Count - 1) + Me.GetColumnWidths(w))
                            End If
                        Next
                    End If
                    If Me.RowCount > 1 Then
                        For h As Integer = 0 To Me.GetRowHeights.Length - 2
                            If h = 0 Then
                                HBorders.Add(Me.GetRowHeights(h))
                            Else
                                HBorders.Add(HBorders(HBorders.Count - 1) + Me.GetRowHeights(h))
                            End If
                        Next
                    End If
    
                    Dim onV As Boolean = (VBorders.Contains(loc.X) Or VBorders.Contains(loc.X - 1) Or VBorders.Contains(loc.X + 1))
                    Dim onH As Boolean = (HBorders.Contains(loc.Y) Or HBorders.Contains(loc.Y - 1) Or HBorders.Contains(loc.Y + 1))
                    If onV And onH Then
                        Me.Cursor = Cursors.SizeAll
                    ElseIf onV Then
                        Me.Cursor = Cursors.VSplit
                    ElseIf onH Then
                        Me.Cursor = Cursors.HSplit
                    Else
                        Me.Cursor = Cursors.Default
                    End If
    
                ElseIf m.Msg = WM_LBUTTONDOWN And Me.Cursor <> Cursors.Default Then
                    Dim loc As Point = Me.PointToClient(MousePosition)
                    selColumn = -1
                    selRow = -1
                    For c As Integer = 0 To VBorders.Count - 1
                        If VBorders(c) >= loc.X - 1 And VBorders(c) <= loc.X + 1 Then
                            selColumn = c
                            Exit For
                        End If
                    Next
                    For r As Integer = 0 To HBorders.Count - 1
                        If HBorders(r) >= loc.Y - 1 And HBorders(r) <= loc.Y + 1 Then
                            selRow = r
                            Exit For
                        End If
                    Next
    
                ElseIf m.Msg = WM_MOUSEMOVE And m.WParam.ToInt32 = MK_LBUTTON Then
                    Dim loc As Point = Me.PointToClient(MousePosition)
                    If Me.Cursor <> Cursors.Default Then
    
                        If selRow > -1 And loc.Y >= 1 And loc.Y <= Me.ClientSize.Height - 2 Then
                            Me.RowStyles(selRow).SizeType = SizeType.Absolute
    
                            Dim ref As Single = loc.Y - Me.RowStyles(selRow).Height
                            If selRow > 0 Then ref -= HBorders(selRow - 1)
    
                            If Me.RowStyles(selRow).Height + ref > 0 Then
    
                                If Me.RowCount > selRow + 1 Then
                                    If Me.RowStyles(selRow + 1).Height - ref < 1 Then Exit Sub
                                    Me.RowStyles(selRow + 1).Height -= ref
                                End If
    
                                Me.RowStyles(selRow).Height += ref
                            End If
                        End If
    
                        If selColumn > -1 And loc.X >= 1 And loc.X <= Me.ClientSize.Width - 2 Then
                            Me.ColumnStyles(selColumn).SizeType = SizeType.Absolute
    
                            Dim ref As Single = loc.X - Me.ColumnStyles(selColumn).Width
                            If selColumn > 0 Then ref -= VBorders(selColumn - 1)
    
                            If Me.ColumnStyles(selColumn).Width + ref > 0 Then
    
                                If Me.ColumnCount > selColumn + 1 Then
                                    If Me.ColumnStyles(selColumn + 1).Width - ref < 1 Then Exit Sub
                                    Me.ColumnStyles(selColumn + 1).Width -= ref
                                End If
    
                                Me.ColumnStyles(selColumn).Width += ref
                            End If
    
                        End If
    
                    End If
    
                ElseIf m.Msg = WM_LBUTTONUP Then
                    selColumn = -1
                    selRow = -1
                End If
            End If
        End Sub
    End Class

      然后你需要build一下你的工程。build之后在工具箱中会自动生成TableLayoutPanelEx控件。你需要把他拉到form中即可。然后有个重要的地方需要注意下:你需要设置RowCountColumnCount属性,达到你想达到的最大值,我们假设为10行10列吧,就设置RowCount等于10,ColumnCount等于10,这些都是在窗口设计模式中做到的。
      接下来,我们再加两个NumericUpDown控件到Form中,命名为 (NUD_Rows) 和 (NUD_Columns)

      最后把下面的代码放到Form中即可。

    Public Class Form1
    
        Public Sub New()
            InitializeComponent()
    
            'Set the minimum of the 2 NumericUpDown controls for the rows and columns to 1
            'Set the maximum of the 2 NumericUpDown controls to the number of rows and columns you have set in the [Design] tab properties
            NUD_Rows.Minimum = 1
            NUD_Rows.Maximum = TableLayoutPanelEx1.RowCount
            NUD_Columns.Minimum = 1
            NUD_Columns.Maximum = TableLayoutPanelEx1.ColumnCount
    
            'Set to the rows and columns counts back to what you want for the default
            TableLayoutPanelEx1.ColumnCount = 4
            TableLayoutPanelEx1.RowCount = 4
    
            'Set the 2 NumericUpDown control values to the current count of rows and columns
            NUD_Rows.Value = TableLayoutPanelEx1.RowCount
            NUD_Columns.Value = TableLayoutPanelEx1.ColumnCount
        End Sub
    
        Private Sub NUD_Rows_ValueChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles NUD_Rows.ValueChanged
            If Me.Created Then TableLayoutPanelEx1.RowCount = CInt(NUD_Rows.Value)
        End Sub
    
        Private Sub NUD_Columns_ValueChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles NUD_Columns.ValueChanged
            If Me.Created Then TableLayoutPanelEx1.ColumnCount = CInt(NUD_Columns.Value)
        End Sub
    End Class

     你可以运行和调试了。Good lucy baby! 

    理想的效果应该是你可以用鼠标改变行高和列宽了。可以通过 NumericUpDown控件改变行数和列数。

    这边是我的效果图:

  • 相关阅读:
    迷 宫
    车厢调度
    快速幂
    2804 最大最小数质因数
    3022 西天收费站
    2291 糖果堆
    1464 装箱问题 2
    Exists/In/Any/All/Contains操作符
    window.onscroll
    zIndex 属性设置元素的堆叠顺序。
  • 原文地址:https://www.cnblogs.com/tony-MSDN/p/4378655.html
Copyright © 2011-2022 走看看