C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

TableLayoutPanelに入ったPictureBox

[トピック内 8 記事 (1 - 8 表示)]  << 0 >>

■96331 / inTopicNo.1)  TableLayoutPanelに入ったPictureBox
  
□投稿者/ 紐 (1回)-(2020/11/11(Wed) 19:34:00)

分類:[.NET 全般] 

VB.NETに関する質問です。

TableLayoutPanelの中に画像を表示したPictureBoxが入っています。
ウインドウサイズを変えた時に、アスペクト比を変えずに
PictureBoxサイズをTableLayoutPanelのサイズにフィットさせたいと考えています。



    'フォームのサイズを変更したときに、PictureBoxサイズが追随して変更するようにする
    Public Sub Form1_SizeChanged() Handles MyBase.SizeChanged

        Call SetPictureBox()

    End Sub


    Private Sub SetPictureBox()

        Dim TL As Size

        TL.Height = frm.TableLayoutPanel9.GetRowHeights(1) - PBox.Margin.Size.Height
        TL.Width = frm.TableLayoutPanel9.GetColumnWidths(0) - PBox.Margin.Size.Width


        Dim SetSize As Size

        Dim BoundaryWidth As Integer = PictureBox1.Width - PictureBox1.ClientSize.Width

        If TL.Height / TL.Width > 1 Then

            SetSize.Width = TL.Width
            SetSize.Height = CInt((SetSize.Width - BoundaryWidth) * ImageAspect) + BoundaryWidth

        Else

            SetSize.Height = TL.Height
            SetSize.Width = CInt((SetSize.Height - BoundaryWidth) / ImageAspect) + BoundaryWidth

        End If


        PictureBox1.Size = SetSize

        PictureBox1.Invalidate()


    End Sub


こんな感じのコードでフィットさせることはできているのですが、
ウインドウサイズを変えた時に
TableLayoutPanelのサイズ変化してから少し遅れてから、
PictureBoxの中身のサイズも変化するため、少しぎこちない感じがします。

これらを同時に更新したいのですが
どのようにすれば良いですか?

Me.SuspendLayout()
Me.ResumeLayout()

の辺りを試してみたのですが
うまくいきませんでした。

どのようなコードなら良いでしょうか?

引用返信 編集キー/
■96335 / inTopicNo.2)  Re[1]: TableLayoutPanelに入ったPictureBox
□投稿者/ KOZ (151回)-(2020/11/12(Thu) 10:09:57)
2020/11/12(Thu) 10:19:53 編集(投稿者)
No96331 (紐 さん) に返信
> TableLayoutPanelの中に画像を表示したPictureBoxが入っています。
> ウインドウサイズを変えた時に、アスペクト比を変えずに
> PictureBoxサイズをTableLayoutPanelのサイズにフィットさせたいと考えています。

TableLayoutPanel を使うときは、位置や大きさを Dock や Anchor に任せたほうが楽かと思います。
自分だったら表示するためのカスタムコントロールを作り、Dock = DockStyle.Fill にして配置します。
下のコードは、画像のアスペクト比を保ったまま表示するカスタムコントロールの例です。

Public Class KeepAspecctPictureBox
    Inherits PictureBox

    Public Sub New()
        SetStyle(ControlStyles.AllPaintingInWmPaint, True)
        SetStyle(ControlStyles.ResizeRedraw, True)
    End Sub

    Protected Overrides Sub OnPaint(pe As PaintEventArgs)
        Using b As New SolidBrush(BackColor)
            pe.Graphics.FillRectangle(b, ClientRectangle)
        End Using
        If Image Is Nothing Then
            Return
        End If
        Dim cs As Size = ClientSize
        Dim imageSize As Size = Image.Size
        Dim drawWidth As Integer
        Dim drawHeight As Integer
        'If cs.Width / cs.Height > imageSize.Width / imageSize.Height Then
        If cs.Width * imageSize.Height > imageSize.Width * cs.Height Then
            drawHeight = cs.Height
            drawWidth = CInt(cs.Height * imageSize.Width / imageSize.Height)
        Else
            drawWidth = cs.Width
            drawHeight = CInt(cs.Width * imageSize.Height / imageSize.Width)
        End If
        pe.Graphics.DrawImage(Me.Image, New Rectangle(0, 0, drawWidth, drawHeight))
    End Sub

End Class

引用返信 編集キー/
■96336 / inTopicNo.3)  Re[2]: TableLayoutPanelに入ったPictureBox
□投稿者/ ぼーちゃん (27回)-(2020/11/12(Thu) 10:17:43)
PictureBoxのアスペクト比が崩れても
表示している画像の比が保たれれば良いのであれば、

PictureBox1.Dock = DockStyle.Fill
PictureBox1.SizeMode = PictureBoxSizeMode.Zoom

だけで行けますがこれだと意図と違ってしまいますかね?
引用返信 編集キー/
■96354 / inTopicNo.4)  Re[3]: TableLayoutPanelに入ったPictureBox
□投稿者/ 紐 (2回)-(2020/11/12(Thu) 17:36:24)
ありがとうございます。

いろいろ考えたのですが
picturebox上をクリックした時に、クリックした箇所の色を変えるなどの機能ももたせているため、
DockStyle.Fillの方法で書くと、コードが複雑になってしまうため、
画像のアスペクト比とpictureboxのアスペクト比を合わせる必要があります。

この方法で、
TableLayoutPanelとPictureBoxを同時に更新する方法があれば
お教えください。
引用返信 編集キー/
■96355 / inTopicNo.5)  Re[4]: TableLayoutPanelに入ったPictureBox
□投稿者/ KOZ (152回)-(2020/11/12(Thu) 20:33:57)
2020/11/12(Thu) 20:34:18 編集(投稿者)

No96354 (紐 さん) に返信
> この方法で、
> TableLayoutPanelとPictureBoxを同時に更新する方法があれば

No96174 は使えないでしょうか?
引用返信 編集キー/
■96356 / inTopicNo.6)  Re[5]: TableLayoutPanelに入ったPictureBox
□投稿者/ 紐 (3回)-(2020/11/13(Fri) 10:26:09)
No96355 (KOZ さん) に返信

ありがとうございます。


Dim dwp As IntPtr = BeginDeferWindowPos(1)

    処理

EndDeferWindowPos(dwp)

とやってみましたが、挙動に変化はありませんでした。
仕様だと思って諦めるしかないでしょうか?
引用返信 編集キー/
■96357 / inTopicNo.7)  Re[6]: TableLayoutPanelに入ったPictureBox
□投稿者/ とっちゃん (704回)-(2020/11/13(Fri) 11:23:34)
No96356 (紐 さん) に返信

後からついてくるように見えるのはおそらく画像があとから再描画されるからだと思います。

一番最初のコードのSetPicuteBoxで、Invalidate() している箇所の直後に
PictureBox1.Update()
を入れることでおそらく、即座に再描画されると思います。

もし、ちらつきがあるということなら、Invalidate( False )とするとちらつきが抑えられると思います。

引用返信 編集キー/
■96362 / inTopicNo.8)  Re[7]: TableLayoutPanelに入ったPictureBox
□投稿者/ 紐 (5回)-(2020/11/15(Sun) 09:26:27)
どうもありがとうございます。

解決済み
引用返信 編集キー/

このトピックをツリーで一括表示


トピック内ページ移動 / << 0 >>

このトピックに書きこむ