4
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

VB 画面サイズに合わせて自由にControlsをリサイズ

Last updated at Posted at 2022-05-15

解像度や画面サイズを意識しない画面レイアウト

端末の解像度やウィンドウサイズを意識せずに画面レイアウトを作成したいが、WinFormsのAnchorでは実現ができない。フォームサイズに合わせて自動で各コントロールのサイズを調整する必要があるが調べたところ既にC#公開されている方がいたのでそれをそのままVBにしたのを備忘録として残す。
TestForm1.pngTestForm2.png

参考

オリジナル
 C# Resize ALL Controls at Runtime
上記のカスタム
 C# 画面サイズに合わせて自由にControlsをリサイズ

Resizeクラス

下記クラスを作成する。

clsResize.vb
Imports System
Imports System.Collections.Generic
Imports System.Linq
Imports System.Text
Imports System.Windows.Forms

Public Class clsResize
    Private _arr_control_storage As List(Of System.Drawing.Rectangle) = New List(Of System.Drawing.Rectangle)()
    Private showRowHeader As Boolean = False
    Private FontTable As Dictionary(Of String, Single)
    Private ControlTable As Dictionary(Of String, System.Drawing.Rectangle)

    Public Sub New(ByVal _form_ As Form)
        form = _form_
        _formSize = _form_.ClientSize
        _fontsize = _form_.Font.Size

        Dim _controls = _get_all_controls(form)
        FontTable = New Dictionary(Of String, Single)()
        ControlTable = New Dictionary(Of String, System.Drawing.Rectangle)()

        For Each control As Control In _controls
            FontTable.Add(control.Name, control.Font.Size)
            ControlTable.Add(control.Name, control.Bounds)
        Next
    End Sub

    Private _fontsize As Single
    Private _formSize As System.Drawing.SizeF
    Private form As Form

    Public Sub _get_initial_size()
        Dim _controls = _get_all_controls(form)

        For Each control As Control In _controls
            _arr_control_storage.Add(control.Bounds)
            If control.[GetType]() = GetType(DataGridView) Then _dgv_Column_Adjust((CType(control, DataGridView)), showRowHeader)
        Next
    End Sub

    Public Sub _resize()
        Dim _form_ratio_width As Double = CDbl(form.ClientSize.Width) / CDbl(_formSize.Width)
        Dim _form_ratio_height As Double = CDbl(form.ClientSize.Height) / CDbl(_formSize.Height)
        Dim _controls = _get_all_controls(form)
        Dim _pos As Integer = -1

        For Each control As Control In _controls
            Me._fontsize = FontTable(control.Name)
            _pos += 1
            Dim _controlSize As System.Drawing.Size = New System.Drawing.Size(CInt((_arr_control_storage(_pos).Width * _form_ratio_width)), CInt((_arr_control_storage(_pos).Height * _form_ratio_height)))
            Dim _controlposition As System.Drawing.Point = New System.Drawing.Point(CInt((_arr_control_storage(_pos).X * _form_ratio_width)), CInt((_arr_control_storage(_pos).Y * _form_ratio_height)))
            control.Bounds = New System.Drawing.Rectangle(_controlposition, _controlSize)
            If control.[GetType]() = GetType(DataGridView) Then _dgv_Column_Adjust((CType(control, DataGridView)), showRowHeader)
            control.Font = New System.Drawing.Font(form.Font.FontFamily, CSng((((Convert.ToDouble(_fontsize) * _form_ratio_width) / 2) + ((Convert.ToDouble(_fontsize) * _form_ratio_height) / 2))))
        Next
    End Sub

    Private Sub _dgv_Column_Adjust(ByVal dgv As DataGridView, ByVal _showRowHeader As Boolean)
        Dim intRowHeader As Integer = 0
        Const Hscrollbarwidth As Integer = 5

        If _showRowHeader Then
            intRowHeader = dgv.RowHeadersWidth
        Else
            dgv.RowHeadersVisible = False
        End If

        For i As Integer = 0 To dgv.ColumnCount - 1
            If dgv.Dock = DockStyle.Fill Then
                dgv.Columns(i).Width = ((dgv.Width - intRowHeader) / dgv.ColumnCount)
            Else
                dgv.Columns(i).Width = ((dgv.Width - intRowHeader - Hscrollbarwidth) / dgv.ColumnCount)
            End If
        Next
    End Sub

    Private Shared Function _get_all_controls(ByVal c As Control) As IEnumerable(Of Control)
        Return c.Controls.Cast(Of Control)().SelectMany(Function(item) _get_all_controls(item)).Concat(c.Controls.Cast(Of Control)()).Where(Function(control) control.Name <> String.Empty)
    End Function
End Class

使い方

①LoadイベントでResizeクラスの_get_initial_sizeを呼ぶ
②SizeChangedイベントでResizeクラスの_resizeを呼ぶ

TestForm.vb
Public Class TestForm

    Private _form_resize As clsResize

    Public Sub New()
        InitializeComponent()

        _form_resize = New clsResize(Me)
        AddHandler Me.Load, AddressOf TestForm_Load
        AddHandler Me.SizeChanged, AddressOf TestForm_SizeChanged
    End Sub

    Private Sub TestForm_Load(sender As Object, e As EventArgs)
        _form_resize._get_initial_size()
    End Sub

    Private Sub TestForm_SizeChanged(sender As Object, e As EventArgs)
        _form_resize._resize()
    End Sub

End Class
4
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?