1

我有一个带有按钮的表单,它将动态创建一个新表单。我根据文本文件即时添加所有标签、文本框和按钮。我想如果表单上有太多控件但它不起作用,我可以使用“ frmDynamic.AutoScroll = True ”命令添加滚动条。这是表单的相关设置

 frmDynamic = New Form()
            frmDynamic.AutoScaleDimensions = New System.Drawing.SizeF(6.0F, 13.0F)
            frmDynamic.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
            frmDynamic.Name = "frmDynamicMerchantApplication"

            'dimension is irrelevant at the moment
            frmDynamic.ClientSize = New System.Drawing.Size(10, 10)
            'the parent will be the current form
            'frm.MdiParent = this;

            frmDynamic.ControlBox = True
            frmDynamic.FormBorderStyle = System.Windows.Forms.FormBorderStyle.Sizable
            ' This needs to be GrowOnly for the auto scroll to work. - otherwise you have to add scrollbars manually along with the handlers and so forth.
            frmDynamic.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowOnly

            ' Add auto scroll since the form could grow out of range when adding multiple references and owners
            frmDynamic.AutoScroll = True

此外,我还尝试设置“ pad.AutoScrollMinSize = new System.Drawing.Size(300, 0) ”属性,但似乎没有任何效果 - 我没有滚动条。

作为最后的测试,我在主窗体上将 AutoScroll 属性设置为 true,当窗体的大小小于对象位置时,它可以正常工作。作为最后的测试,我在主窗体上添加了另一个按钮,使用以下代码创建一个自动滚动设置为 true 的窗体,它工作正常。

 ' Create a new form.
        Dim form2 As New Form()
        ' Create a button to add to the new form.
        Dim button1 As New Button()
        ' Set text for the button.
        button1.Text = "Scrolled Button"
        ' Set the size of the button.
        button1.Size = New Size(100, 30)
        ' Set the location of the button to be outside the form's client area.
        button1.Location = New Point(form2.Size.Width + 200, form2.Size.Height + 200)

        ' Add the button control to the new form.
        form2.Controls.Add(button1)
        ' Set the AutoScroll property to true to provide scrollbars.
        form2.AutoScroll = True

        ' Display the new form as a dialog box.
        form2.ShowDialog()

是否有任何表单设置可以停止此功能?

这是整个表单创建代码:

 ' Creating dynamic form and dynamic objects in it.
        If Not IsNothing(colMerchApplicationFromWebService) Then
            ' vertical position of current object we are working with on the form
            Dim intVertPos As Integer = 35

            'variables to hold dimensions for objects on the form. Used in calculations for creating objects and their placement
            Dim intMaxWidthLabel As Integer = 0
            Dim intMaxWidthText As Integer = 0
            Dim iFrmMaxHeight As Integer = 0
            Dim intWidthTextBox As Integer = 0
            Dim intGapHeight As Integer = 0
            Dim measureString As String = ""
            Dim stringFont As Font = Nothing
            Dim stringSize As SizeF
            Dim iTabIndex As Integer = 0
            Dim iNewLineCount As Integer = 0
            Dim iNewColumnPosition As Integer = 0

            ' Font settings
            Dim sFont As String = "Arial"
            Dim sSizeFont As String = "10"
            Dim sTextSize As String = "15"
            Dim pictureBox1 As New PictureBox

            ' use an invisible picture box that will help to graphically
            ' measure strings according their font and font size
            Dim myGraphics As Graphics = pictureBox1.CreateGraphics()

            ' Calculate the height gap that has to be generated for this calculation, we have to follow the principles listed:
            '   The gap should be determined only by the height of the tallest object on window: the textBox.
            '   Simulate the drawing of a dummy textBox, that will never be shown, and retrieve its height for spacing purposes.
            Dim dummyTextBox As New TextBox()
            dummyTextBox.Font = New System.Drawing.Font(sFont, Single.Parse(sSizeFont), System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CByte(0))
            Dim intHeight As Integer = Integer.Parse(sSizeFont) + Integer.Parse(sSizeFont) / 2
            dummyTextBox.Name = "TextBoxDummy"
            intGapHeight = dummyTextBox.Height

            'close the dynamic form if existing already
            If frmDynamic IsNot Nothing Then
                frmDynamic.Close()
            End If

            ' Now create a new fresh one
            frmDynamic = New Form()
            frmDynamic.AutoScaleDimensions = New System.Drawing.SizeF(6.0F, 13.0F)
            frmDynamic.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
            frmDynamic.Name = "frmDynamicMerchantApplication"

            'dimension is irrelevant at the moment
            frmDynamic.ClientSize = New System.Drawing.Size(10, 10)
            'the parent will be the current form
            'frm.MdiParent = this;

            frmDynamic.ControlBox = True
            frmDynamic.FormBorderStyle = System.Windows.Forms.FormBorderStyle.Sizable
            ' This needs to be GrowOnly for the auto scroll to work. - otherwise you have to add scrollbars manually along with the handlers and so forth.
            frmDynamic.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowOnly

            ' Add auto scroll since the form could grow out of range when adding multiple references and owners
            frmDynamic.AutoScroll = True
            frmDynamic.BackColor = System.Drawing.Color.LightGray

            'for each parameter returned add a data entry control to the form
            For Each itemMerchantAppField As TestApp.parameter In colMerchApplicationFromWebService
                ' if we run into a collection it is used for detailed information. We store the collections in the collections dictionary so we can write values and pass them around as needed
                If itemMerchantAppField.ParameterType = "System.Collections" Then
                    ' Create a form level variable to hold the collection
                    dicCollections.Add(itemMerchantAppField.ParameterName, itemMerchantAppField.SubCollection)
                End If

                ' I assume a max of 35 fields in one column for my form and its size. (The field count is based on what looked right for my monitor not exactly Dynamic but its only a test form) 
                If iNewLineCount > 35 Then
                    ' Reset vertical position and counter
                    iNewLineCount = 0
                    iNewColumnPosition = iNewColumnPosition + (intMaxWidthLabel + intMaxWidthText + 20)
                    If intVertPos > iFrmMaxHeight Then
                        iFrmMaxHeight = intVertPos
                    End If
                    intVertPos = 35
                End If

                ' Kick the counter
                iNewLineCount = iNewLineCount + 1

                'add a label object
                Dim aLabel As New Label()
                aLabel.Font = New System.Drawing.Font(sFont, Single.Parse(sSizeFont), System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CByte(0))
                'back color is for testing purposes, to see if the control fits correctly
                aLabel.BackColor = System.Drawing.Color.AliceBlue
                aLabel.Location = New System.Drawing.Point(iNewColumnPosition, intVertPos)

                ' Set up string.
                measureString = itemMerchantAppField.ParameterName
                stringFont = New Font(sFont, Single.Parse(sSizeFont))
                ' Measure string.
                stringSize = New SizeF()
                stringSize = myGraphics.MeasureString(measureString, stringFont)
                Dim intWidthLabel As Integer = 10 + Integer.Parse(stringSize.Width.ToString("####0"))
                'store the biggest width, so that the textboxes can be vertically aligned
                If intWidthLabel > intMaxWidthLabel Then
                    intMaxWidthLabel = intWidthLabel
                End If
                aLabel.Size = New System.Drawing.Size(intWidthLabel, intGapHeight)
                aLabel.Name = "lbl" & itemMerchantAppField.ParameterName
                aLabel.Text = itemMerchantAppField.ParameterName

                frmDynamic.SuspendLayout()
                aLabel.SuspendLayout()
                frmDynamic.Controls.Add(aLabel)

                ' Size of textBox padding with "W" the largest char in ascii representation.
                ' Basically we are setting the textbox widths based on the lengths of the field name plus 15 w's
                ' We should be setting this based on the allowed field length as w's up to the max amount we allow(here is it coded to be 30)
                ' this section needs to be corrected
                Dim chrPadding As Char = "W"c
                If Integer.Parse(sTextSize) > 30 Then
                    measureString = measureString.PadRight(30, chrPadding)
                Else
                    measureString = measureString.PadRight(Integer.Parse(sTextSize), chrPadding)
                End If
                stringFont = New Font(sFont, Single.Parse(sSizeFont))
                ' Measure string.
                stringSize = New SizeF()
                stringSize = myGraphics.MeasureString(measureString, stringFont)
                intWidthTextBox = Integer.Parse(stringSize.Width.ToString("####0"))

                ''For Each item As wsMerchantApp.parameter In itemMerchantAppField 
                ' Add a text box object
                Dim aTextBox As New TextBox()
                aTextBox.Font = New System.Drawing.Font(sFont, Single.Parse(sSizeFont), System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CByte(0))
                aTextBox.BackColor = System.Drawing.Color.Yellow
                aTextBox.Location = New System.Drawing.Point(iNewColumnPosition + 5 + intMaxWidthLabel, intVertPos)
                aTextBox.Size = New System.Drawing.Size(intWidthTextBox + 10, intGapHeight)

                ' Add a double click handler for each text box - I use this for getting additional information on the field in focus
                AddHandler aTextBox.DoubleClick, AddressOf TextBoxShowDesc

                'store the biggest width, so that the textboxes can be vertically aligned
                If intWidthTextBox > intMaxWidthText Then
                    intMaxWidthText = intWidthTextBox
                End If

                ' giving a name to all your objects will be the only way to retrieve them and use them in code. I use the names from
                ' the parameter class so it is easier to work with
                aTextBox.Name = itemMerchantAppField.ParameterName
                'giving the maximum size in characters for the textbox.
                aTextBox.MaxLength = Integer.Parse(itemMerchantAppField.ParameterLength)
                ' Create a useful tooltip
                ToolTip1.SetToolTip(aTextBox, itemMerchantAppField.ParameterDesc & IIf(itemMerchantAppField.ParameterRequired, " This field is required.", " This field is not required."))

                'tab have to be ordered so we can navigate the form with ease
                aTextBox.TabIndex = iTabIndex
                ' Now kick the counter
                iTabIndex += 1

                'Vertical position is to be manage according the 
                'tallest object in the form, in this case the textbox it self
                intVertPos += intGapHeight

                'adding the textbox to the form
                frmDynamic.SuspendLayout()
                aTextBox.SuspendLayout()
                frmDynamic.Controls.Add(aTextBox)
            Next

            'put an action button to the right
            Dim btnFill As Button = New System.Windows.Forms.Button()
            btnFill.Location = New System.Drawing.Point(iNewColumnPosition + (intMaxWidthLabel + intMaxWidthText), 0) 'intMaxWidthLabel + intWidthTextBox + 20, 0)
            btnFill.Name = "btnFill"
            btnFill.Size = New System.Drawing.Size(75, 23)
            btnFill.TabIndex = iTabIndex
            btnFill.Text = "&Fill"

            'put another action button to the under the first
            Dim btnSendApp As Button = New System.Windows.Forms.Button()
            btnSendApp.Location = New System.Drawing.Point(iNewColumnPosition + (intMaxWidthLabel + intMaxWidthText), 0 + intGapHeight) 'intMaxWidthLabel + intWidthTextBox + 20, 0)
            btnSendApp.Name = "btnSubmit"
            btnSendApp.Size = New System.Drawing.Size(75, 23)
            btnSendApp.TabIndex = iTabIndex
            btnSendApp.Text = "&Submit"

            'define a click_event on the buttons - now we can handle the click event code in the parent form.
            AddHandler btnFill.Click, AddressOf btnFillClick
            AddHandler btnSendApp.Click, AddressOf btnSendAppClick

            ' Add the buttons
            frmDynamic.Controls.Add(btnFill)
            frmDynamic.Controls.Add(btnSendApp)

            ' Grow the form if needed to fir objects
            frmDynamic.Width = iNewColumnPosition + (intMaxWidthLabel + intMaxWidthText + 95) 'intMaxWidthLabel + intMaxWidthText + 95
            frmDynamic.Height = iFrmMaxHeight + 35 'intVertPos + 35
            If frmDynamic.Height > Screen.PrimaryScreen.WorkingArea.Height OrElse frmDynamic.Width > Screen.PrimaryScreen.WorkingArea.Width Then
                ' If the form is too big we should warn the user. 
                MessageBox.Show("Beware! The size of the window is bigger than your actual definitions...", "Warning", MessageBoxButtons.OK)
            End If

            frmDynamic.Show()
        Else
            MsgBox("ERROR: Nothing returned from the web service. The form can not be created.")
        End If
4

1 回答 1

1

经过快速测试,我可以确认您的代码没有问题;很可能,您没有进行正确的测试。下面我在您的第一个代码中添加了一些位来说明这一点:

frmDynamic = New Form()
frmDynamic.AutoScaleDimensions = New System.Drawing.SizeF(6.0F, 13.0F)
frmDynamic.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
frmDynamic.Name = "frmDynamicMerchantApplication"

'dimension is irrelevant at the moment
frmDynamic.ClientSize = New System.Drawing.Size(50, 50)
'the parent will be the current form
'frm.MdiParent = this;

frmDynamic.ControlBox = True
frmDynamic.FormBorderStyle = System.Windows.Forms.FormBorderStyle.Sizable
' This needs to be GrowOnly for the auto scroll to work. - otherwise you have to add scrollbars manually along with the handlers and so forth.
frmDynamic.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowOnly

' Add auto scroll since the form could grow out of range when adding multiple references and owners
frmDynamic.AutoScroll = True

Dim testButton As New Button()
frmDynamic.Controls.Add(testButton)
testButton.Top = frmDynamic.Height + 1

frmDynamic.Show()

这段代码显示了一个弹出的表单和相应的垂直滚动条(我增加了大小,否则你甚至看不到滚动条,但这根本没有效果)。

如果现在将位置更改testButton为 -1(或 -100),滚动条将停止出现;我想这是你看不到滚动条的原因:一个错误定位的测试对象。

- 更新

查看您的整个代码后,问题似乎出在所有frmDynamic.SuspendLayout()位(MSDN 中有关此的信息)中,只需删除它们即可。知道代码的每一位到底是什么是一件好事。此外,当您遇到无法理解的问题和正常工作的代码(此答案中的代码)时,无论它多么简单;一个好的过程是逐步将错误代码中的位包含在工作代码中,直到找到问题所在。

于 2013-08-07T16:01:29.907 回答