none
フォームサイズの自動調整について RRS feed

  • 質問

  • こんにちは、お世話になっております。

     

    フォームにListViewを設定して、起動時にDBからデータをListViewに表示させています。

    現状では、下記のように縦最大で表示させていますが、

    (横幅は(840)で固定にしてあります)

     Dim h, w As Integer
            w = System.Windows.Forms.Screen.GetWorkingArea(Me).Width / 2

            h = System.Windows.Forms.Screen.GetWorkingArea(Me).Height
            Me.SetBounds(w - 420, 0, 840, h, BoundsSpecified.All)

     

    これでは、起動時にDBから呼び出したデータの件数が少ない時は、

    余分の列が表示されて、すっきりしないので、下記のようにしたいと考えています。

     

     h = System.Windows.Forms.Screen.GetWorkingArea(Me).Height

    ListView「h」までデータがない限り、フォームの縦幅をスクロールバーが表示する直前まで、

    自動でデータがある場所に縦幅を調整したい。(データが「h」まであったら縦幅を最大にする)

     

    同じように、横幅も現状では、固定にしてありますが、これも、

    自動でスクロールバーが表示する直前まで横幅に設定したい。

     

    以上ご教示の程よろしくお願致します。

    2008年5月8日 10:38

回答

  • 例をすんなり書こうと思っていたのですが、

    冷静に読んでいると「理屈(考え方)」について、どう考えているか、どこまで考えたのか、考えることすらしていないのか、何がわかっていて何がわからないのか。

    そういうことが何も書いてないなぁ。

     

    本題。

     

    理屈は結構単純です。

    横幅は、最右列の右端の境界線までの必要幅がわかれば収まるかどうかだけ。

    縦幅は、同様にアイテムの高さx行数の高さがわかれば収まるかどうかだけ。

    ※ともにスクロールバーの幅と高さは当然考慮する。

     

    理屈がわかれば、MSDNを調べる。

    ListViewだからListViewとListViewItemとListViewSubItemを調べる。

    そうすると、ListViewItem.Boundsというのが見つかる。

    うん、使えそう。

    #と、ここまでは誰しもやってほしいことです。

     

    で、ロジックを考える前にポイントがります。

    Controlでこういう位置調整みたいなことをやるときはClientSizeとClientRectangleがポイントです。

    フォームに貼り付ける領域は外枠の内側が(0,0)ですよね。

    その内側の領域がクライアント領域です。

    ListViewもControlですから収まるかどうかはListViewのクライアント領域と比較する必要があります。

     

    もう一つはスクロールバーの高さと幅ですが、これについてはSystemInformationクラスを調べてください。

    で、アイテムの枠線部分も考慮しなければいけない場合はBorderSizeプロパティが使えるかもしれません。

    値がわかればあとはスクロールバーが表示されているかどうかの判断ですね。

    こればっかりはリサイズしながら毎回判断しなければなりません。

    そういう意味では最大サイズから縮めていく方法がよいでしょう。

     

    最後に高さについてですが、収まるかどうかの判断にAPIを使用する方法があります。

    LVM_GETCOUNTPERPAGEメッセージを呼び出すと、その時のListViewのサイズにおける完全に可視状態の行数を求めることができます。

    リサイズしながらそれを呼び出して判断する方法です。

    2008年5月8日 13:06
  • まどか さん、ご回答どうもありがとうございます。

     

    おかげさまで、意外と簡単にできました。

     

       Dim w, h, hh, mh As Integer
            w = System.Windows.Forms.Screen.GetWorkingArea(Me).Width / 2

            hh = System.Windows.Forms.Screen.GetWorkingArea(Me).Height
            h = ListView1.Items.Count * 30

           >縦幅は、同様にアイテムの高さx行数の高さがわかれば収まるかどうかだけ。

       
            mh = hh - h

            If mh <= 0 Then
                Me.SetBounds(w - 375, 0, 750, h, BoundsSpecified.All)
            Else
                Me.SetBounds(w - 375, (hh - h) / 2, 750, h, BoundsSpecified.All)
            End If

     

    >横幅は、最右列の右端の境界線までの必要幅がわかれば収まるかどうかだけ。

    横幅は、固定にしても問題なさそうですので、今回は固定(750)にしました。

     

    以上で、できました。どうも有難うございました。

    2008年5月9日 6:36

すべての返信

  • 例をすんなり書こうと思っていたのですが、

    冷静に読んでいると「理屈(考え方)」について、どう考えているか、どこまで考えたのか、考えることすらしていないのか、何がわかっていて何がわからないのか。

    そういうことが何も書いてないなぁ。

     

    本題。

     

    理屈は結構単純です。

    横幅は、最右列の右端の境界線までの必要幅がわかれば収まるかどうかだけ。

    縦幅は、同様にアイテムの高さx行数の高さがわかれば収まるかどうかだけ。

    ※ともにスクロールバーの幅と高さは当然考慮する。

     

    理屈がわかれば、MSDNを調べる。

    ListViewだからListViewとListViewItemとListViewSubItemを調べる。

    そうすると、ListViewItem.Boundsというのが見つかる。

    うん、使えそう。

    #と、ここまでは誰しもやってほしいことです。

     

    で、ロジックを考える前にポイントがります。

    Controlでこういう位置調整みたいなことをやるときはClientSizeとClientRectangleがポイントです。

    フォームに貼り付ける領域は外枠の内側が(0,0)ですよね。

    その内側の領域がクライアント領域です。

    ListViewもControlですから収まるかどうかはListViewのクライアント領域と比較する必要があります。

     

    もう一つはスクロールバーの高さと幅ですが、これについてはSystemInformationクラスを調べてください。

    で、アイテムの枠線部分も考慮しなければいけない場合はBorderSizeプロパティが使えるかもしれません。

    値がわかればあとはスクロールバーが表示されているかどうかの判断ですね。

    こればっかりはリサイズしながら毎回判断しなければなりません。

    そういう意味では最大サイズから縮めていく方法がよいでしょう。

     

    最後に高さについてですが、収まるかどうかの判断にAPIを使用する方法があります。

    LVM_GETCOUNTPERPAGEメッセージを呼び出すと、その時のListViewのサイズにおける完全に可視状態の行数を求めることができます。

    リサイズしながらそれを呼び出して判断する方法です。

    2008年5月8日 13:06
  • まどか さん、ご回答どうもありがとうございます。

     

    おかげさまで、意外と簡単にできました。

     

       Dim w, h, hh, mh As Integer
            w = System.Windows.Forms.Screen.GetWorkingArea(Me).Width / 2

            hh = System.Windows.Forms.Screen.GetWorkingArea(Me).Height
            h = ListView1.Items.Count * 30

           >縦幅は、同様にアイテムの高さx行数の高さがわかれば収まるかどうかだけ。

       
            mh = hh - h

            If mh <= 0 Then
                Me.SetBounds(w - 375, 0, 750, h, BoundsSpecified.All)
            Else
                Me.SetBounds(w - 375, (hh - h) / 2, 750, h, BoundsSpecified.All)
            End If

     

    >横幅は、最右列の右端の境界線までの必要幅がわかれば収まるかどうかだけ。

    横幅は、固定にしても問題なさそうですので、今回は固定(750)にしました。

     

    以上で、できました。どうも有難うございました。

    2008年5月9日 6:36