Home All Groups Group Topic Archive Search About

Frustrated, Bothered and Bewildered (Form AutoScroll Broken)

Author
14 Jun 2009 5:46 PM
eBob.com
I have a nearly empty form.  In the designer I set Autoscroll to True.  At
run time I dynamically add a DataGridView which is larger than the form.
That should result in Form scroll bars (the DataGridView is larger than the
form) but does not.  Unless I squeeze the form down to a really small size.

All of many attempts to reproduce the problem in a really simple program
have failed.  But the code that fails is fairly brief and simple.  So I have
included it below and hope that someone who is bored today might take a look
and see if they spot anything, or maybe even try it.

In the designer I create a button named btnSpecifyFolder (drive/folder info
is used to populate the DataGridView), a FolderBrowserDiaglog (default name)
and set the form AutoScroll to True.  I also set the size of the form so
that once the
DataGridView is added the scroll bars will be required.

Thanks for any help you can give me.  Code's below.  Bob

Option Strict On
Option Explicit On

Imports System.IO
Imports System.ComponentModel


Public Class Form1

    Class MasterDGVRowTag ' used for rows in the MasterDGV

    End Class

    Dim DriveFolder As String
    Dim di As DirectoryInfo
    Dim MasterDGV As DataGridView
    Dim diArray As DirectoryInfo()

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load

    End Sub

    Private Sub btnSpecifyFolder_Click(ByVal sender As System.Object, ByVal
e As System.EventArgs) Handles btnSpecifyFolder.Click
        Dim FBDresult As Integer = FolderBrowserDialog1.ShowDialog()
        If FBDresult = DialogResult.OK Then
            DriveFolder = FolderBrowserDialog1.SelectedPath
            'MsgBox("selectedpath is """ & DriveFolder & """")
            di = New DirectoryInfo(DriveFolder)
        End If

        diArray = di.GetDirectories
        CreateMasterDGV() ' go create and populate the MasterDGV

        Me.Controls.Add(MasterDGV)
    End Sub

    Sub CreateMasterDGV()

        '
        ' create empty DGV
        '

        MasterDGV = New DataGridView

        With MasterDGV
            .Anchor = DirectCast(AnchorStyles.Bottom + AnchorStyles.Left +
AnchorStyles.Right + AnchorStyles.Top, AnchorStyles)

        End With

        SetupMasterDGV(MasterDGV)

        AddHandler MasterDGV.CellMouseClick, AddressOf
MasterDGV_CellMouseClick

        '
        ' now populate the MasterDGV
        '

        For Each directory As DirectoryInfo In diArray
            Try
                AddRow2(directory.Name, directory.LastAccessTime,
directory.CreationTime, directory.LastWriteTime)
            Catch
            End Try
        Next

        MasterDGV.Height = MasterDGV.Rows.Item(0).Height *
MasterDGV.Rows.Count _
                + MasterDGV.ColumnHeadersHeight ' set height of Master seg.
we've been working on
    End Sub

    Sub AddRow2(ByRef dirname As String, _
                ByRef lat As Date, ByRef law As Date, ByRef cd As Date)

        Dim AddedRowIndex As Integer

        Dim dgvr As New DataGridViewRow
        dgvr.CreateCells(MasterDGV)
        dgvr.Cells(0).Value = "+"
        dgvr.Cells(1).Value = dirname
        'dgvr.Cells(2).Value = filename
        dgvr.Cells(3).Value = lat
        dgvr.Cells(4).Value = cd
        dgvr.Cells(5).Value = law
        'dgvr.Cells(6).Value = length
        AddedRowIndex = MasterDGV.Rows.Add(dgvr) ' add row, get newly added
row's index
        'MasterDGV.Rows.Item(AddedRowIndex).Tag = New MasterDGVRowTag(True,
False)
        MasterDGV(1, 1).ToolTipText = "detail data"

    End Sub 'AddRow2

    Private Sub MasterDGV_CellMouseClick(ByVal sender As Object, ByVal e As
DataGridViewCellMouseEventArgs)

        If e.RowIndex = -1 Then Exit Sub ' ignore clicks in header row

    End Sub

    Sub SetupMasterDGV(ByVal dgv As DataGridView)

        ' the Height is not set here as that has to be set after it is
populated

        dgv.ColumnCount = 7

        With dgv

            .Location = New Point(0, 40)

            .AllowUserToOrderColumns = False ' because this doesn't work
when the master table is segmented

            .Width = 500

            .ColumnHeadersBorderStyle = DataGridViewHeaderBorderStyle.Single

            With .ColumnHeadersDefaultCellStyle
                .BackColor = Color.Navy
                .ForeColor = Color.White
                .Font = New Font(MasterDGV.Font, FontStyle.Bold)
            End With

            .CellBorderStyle = DataGridViewCellBorderStyle.Single
            .GridColor = Color.Black
            .RowHeadersVisible = False
            .ScrollBars = ScrollBars.Horizontal

            .AllowUserToAddRows = False
            .AllowUserToDeleteRows = False
            .AllowUserToOrderColumns = True
            .ReadOnly = True

            With .Columns(0)
                .Width = 20
                .ValueType = GetType(String)
            End With

            With .Columns(1)
                .Name = "Directory"
                .ValueType = GetType(String)
                .Width = 200
            End With

            With .Columns(2)
                .Name = "FileName"
                .ValueType = GetType(String)
            End With

            With .Columns(3)
                .Name = "Last Accessed"
                .ValueType = GetType(Date)
                .Width = 150
            End With

            With .Columns(4)
                .Name = "Create Date"
                .ValueType = GetType(Date)
                .Width = 150
                .Visible = False
            End With

            With .Columns(5)
                .Name = "Last Written"
                .ValueType = GetType(Date)
                .Width = 150
                .Visible = False
            End With

            With .Columns(6)
                .Name = "Size"
                .ValueType = GetType(Long)
                .DefaultCellStyle.Format = "n0"
                .HeaderCell.Style.Alignment =
DataGridViewContentAlignment.MiddleRight
                .DefaultCellStyle.Alignment =
DataGridViewContentAlignment.MiddleRight
            End With

            .SelectionMode = DataGridViewSelectionMode.FullRowSelect
            .MultiSelect = False

        End With

    End Sub 'SetupMasterDGV

End Class

Author
14 Jun 2009 9:15 PM
Armin Zingler
eBob.com wrote:
>        MasterDGV = New DataGridView
>
>        With MasterDGV
>            .Anchor = DirectCast(AnchorStyles.Bottom +
> AnchorStyles.Left + AnchorStyles.Right + AnchorStyles.Top,
> AnchorStyles)
>        End With


If you anchor the control, it is automatically resized and is never larger
than the Form. Consequently, no scrollbars are shown.

(BTW, if you replace "+" by "Or", you can remove DirectCast; because
the AnchorStyles Enum has an attached Flags-attribute)


Armin
Author
15 Jun 2009 2:21 AM
eBob.com
Show quote Hide quote
"Armin Zingler" <az.nospam@freenet.de> wrote in message
news:eSV5MVT7JHA.5932@TK2MSFTNGP03.phx.gbl...
> eBob.com wrote:
>>        MasterDGV = New DataGridView
>>
>>        With MasterDGV
>>            .Anchor = DirectCast(AnchorStyles.Bottom +
>> AnchorStyles.Left + AnchorStyles.Right + AnchorStyles.Top,
>> AnchorStyles)
>>        End With
>
>
> If you anchor the control, it is automatically resized and is never larger
> than the Form. Consequently, no scrollbars are shown.
>
> (BTW, if you replace "+" by "Or", you can remove DirectCast; because
> the AnchorStyles Enum has an attached Flags-attribute)
>
>
> Armin
>

Thank you Armin.  I suspected something along those lines but commented out
the Anchor setting and got the same result.  Of course I didn't realize that
I was setting the Anchor property in two places!!!!

If I have my head correctly wrapped around this, then there is no way for a
DataGridView, via anchoring, to take advantage of the user making the form
larger without paying a penalty when the user makes the form smaller.  The
form is not going to provide a scroll bar when the form is made too small
because the control is anchored.  And it doesn't do any good to specify
scroll bars for the DataGridView because it's been resized to the point
where a scroll bar is not necessary.  That's what I conclude since I have a
horizontal scroll bar for the DataGridView which I never see when it is
anchored and I make the form too small.

BTW, a hack which gets the result I'd like to see is to place an invisible
label just to the lower, right of the DataGridView.  (There's already a
button in the upper, left.)

When I have a chance I will have to investigate docking.  Maybe that will
work the way I'd like it too.  Otherwise, if I decide it's really worth it,
I can do whatever my little heart pleases in a Form.SizeChanged event
handler.

Thanks for the tip re Or'ing the AnchorStyles Enums.  I was surprised when I
needed, or thought I needed, the DirectCast but didn't take the time to
investigate.  I have never looked into the Flags-attribute.

Thanks again,  Bob