Visual Basic 2008 Professional EditionのListView(もしくは入手が容易かつ、商用に組み込む場合に条件の少ない類似のコンポーネント)で質問です。

なんとか工夫して、Windows7のエクスプローラで表示方法をコンテンツにした時のような見栄えにはできないでしょうか?

具体的な要件は以下の通りです。
1.ViewはDetailsで
2.自分のコード上でサイズ設定した上で、画像を表示するようにしたい
 (SmallIconのサイズは小さすぎます)
3.複数行を表示したい
4.item内の文字を、部分部分で変えれるとなおよい

以下文字数制限に引っかかったので、コメント欄に記載します。
VB.NET2008に詳しい方、よろしくお願いします。

回答の条件
  • 1人5回まで
  • 登録:
  • 終了:2011/07/02 23:18:29
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

ベストアンサー

id:heke2mee No.2

回答回数162ベストアンサー獲得回数43

ポイント100pt

複数行や部分的な色を変更するにはオーナードローで行います。

オーナードローでやると、自分でアイコンの絵や、罫線、文字、フォーカス時の

色などは自分で描画する必要があります。


行の高さは、イメージリストのサイズで決まります。

描画はDrawItemイベントやDrawSubItemイベントで行います。

Public Class Form1

    Public Sub New()

        ' この呼び出しは、Windows フォーム デザイナで必要です。
        InitializeComponent()

        ' InitializeComponent() 呼び出しの後で初期化を追加します。

        Me.ListView1.View = View.Details
        Me.ListView1.OwnerDraw = True


    End Sub


    Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        Dim files As String() = System.IO.Directory.GetFiles( _
            System.Environment.GetFolderPath(Environment.SpecialFolder.Personal), "*", System.IO.SearchOption.TopDirectoryOnly)

        Dim file As String
        Dim imageList As New ImageList()
        Me.ListView1.Columns.Add("ファイル名", 200)
        Me.ListView1.SmallImageList = imageList
        Dim width As Integer = 48
        Dim height As Integer = 48

        imageList.ImageSize = New Size(width, height)

        Dim idx As Integer = 0

        For Each file In files
            Dim appIcon As Icon
            appIcon = System.Drawing.Icon.ExtractAssociatedIcon(file)
            imageList.Images.Add(appIcon.ToBitmap())

            Dim fileName As String
            fileName = System.IO.Path.GetFileName(file)
            ' リストビューアイテム作成
            Dim item As ListViewItem = New ListViewItem(fileName)

            Me.ListView1.Items.Add(item)
            Me.ListView1.Items(idx).ImageIndex = idx

            idx += 1
        Next


    End Sub

    Private Sub ListView1_DrawItem(ByVal sender As Object, ByVal e As System.Windows.Forms.DrawListViewItemEventArgs) Handles ListView1.DrawItem
        Dim g As Graphics
        g = e.Graphics
        Dim drawString As String
        Dim drawString2 As String
        drawString = "AAA" + vbCrLf + "BBB"
        drawString2 = "CCC" + e.ItemIndex.ToString

        Dim rect As Rectangle
        rect = e.Bounds
        '背景描画
        If e.Item.Selected = True Then
            g.FillRectangle(Brushes.SkyBlue, rect)
        Else
            g.FillRectangle(Brushes.Yellow, rect)
        End If
        '罫線の描画
        Using pen As New Pen(Color.Gray)
            g.DrawRectangle(pen, rect)
        End Using
        '文字の描画位置
        rect.Location = New Point(e.Bounds.Left + e.Item.ImageList.Images(e.ItemIndex).Width, e.Bounds.Top)
        '文字を書く
        g.DrawString(drawString, Me.ListView1.Font, Brushes.Black, rect)

        Dim stringSize As SizeF = g.MeasureString(drawString, Me.ListView1.Font)
        '文字を書く
        g.DrawString(drawString2, Me.ListView1.Font, Brushes.Red, rect.Location.X, rect.Location.Y + stringSize.Height)

        g.DrawImage(e.Item.ImageList.Images(e.ItemIndex), e.Bounds.Location)
    End Sub

End Class

id:halohalolin

heke2meeさん大変ありがとうございます。

ListViewもやればできる子なんですね(ずいぶんコードが必要ですけど)。 

試してみましたところ、ヘッダー部分の表示がおかしかったので

Private Sub ListView1_DrawColumnHeader(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DrawListViewColumnHeaderEventArgs) Handles ListView1.DrawColumnHeader

e.DrawDefault = True

End Sub

という表示を付け加えて対応しました。

あと、選択色がBrushes.SkyBlue、非選択色がBrushes.Yellowになっていますが、ここは何とかシステムカラーでできないか調べてみます。

2011/06/27 10:40:22

その他の回答1件)

id:heke2mee No.1

回答回数162ベストアンサー獲得回数43

ポイント100pt

こんな感じのことをやりたかったのでしょうか?

Details表示でアイコンサイズを変更する方法


フォームにListViewを貼り付けてください。

実行するとマイドキュメント内のファイル名とアイコンを表示します。

Public Class Form1

    Public Sub New()

        ' この呼び出しは、Windows フォーム デザイナで必要です。
        InitializeComponent()

        ' InitializeComponent() 呼び出しの後で初期化を追加します。

        Me.ListView1.View = View.Details

    End Sub


    Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        Dim files As String() = System.IO.Directory.GetFiles( _
            System.Environment.GetFolderPath(Environment.SpecialFolder.Personal), "*", System.IO.SearchOption.TopDirectoryOnly)

        Dim file As String
        Dim imageList As New ImageList()
        Me.ListView1.Columns.Add("ファイル名", 200)
        Me.ListView1.SmallImageList = imageList
        Dim width As Integer = 32
        Dim height As Integer = 32

        imageList.ImageSize = New Size(width, height)

        Dim idx As Integer = 0

        For Each file In files
            Dim appIcon As Icon
            appIcon = System.Drawing.Icon.ExtractAssociatedIcon(file)
            imageList.Images.Add(appIcon.ToBitmap())

            Dim fileName As String
            fileName = System.IO.Path.GetFileName(file)
            ' リストビューアイテム作成
            Dim item As ListViewItem = New ListViewItem(fileName)

            Me.ListView1.Items.Add(item)
            Me.ListView1.Items(idx).ImageIndex = idx

            idx += 1
        Next


    End Sub
End Class

id:halohalolin

heke2meeさんありがとうございます。

 

まだ実際の動作は確認していないのですが、1と2はImageListで解決できるのですね。

 

では、3はいかがでしょうか?

heke2meeさんの例であれば、画像の隣にファイル名と作成日時を縦に並べて表示させてみるような感じです。

 

普通にやってみた場合、listviewには1行の高さを入れるような項目がプロパティを探しても見当たらないですし、改行を入れても無視されて表示される印象です。

2011/06/26 09:50:03
id:heke2mee No.2

回答回数162ベストアンサー獲得回数43ここでベストアンサー

ポイント100pt

複数行や部分的な色を変更するにはオーナードローで行います。

オーナードローでやると、自分でアイコンの絵や、罫線、文字、フォーカス時の

色などは自分で描画する必要があります。


行の高さは、イメージリストのサイズで決まります。

描画はDrawItemイベントやDrawSubItemイベントで行います。

Public Class Form1

    Public Sub New()

        ' この呼び出しは、Windows フォーム デザイナで必要です。
        InitializeComponent()

        ' InitializeComponent() 呼び出しの後で初期化を追加します。

        Me.ListView1.View = View.Details
        Me.ListView1.OwnerDraw = True


    End Sub


    Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        Dim files As String() = System.IO.Directory.GetFiles( _
            System.Environment.GetFolderPath(Environment.SpecialFolder.Personal), "*", System.IO.SearchOption.TopDirectoryOnly)

        Dim file As String
        Dim imageList As New ImageList()
        Me.ListView1.Columns.Add("ファイル名", 200)
        Me.ListView1.SmallImageList = imageList
        Dim width As Integer = 48
        Dim height As Integer = 48

        imageList.ImageSize = New Size(width, height)

        Dim idx As Integer = 0

        For Each file In files
            Dim appIcon As Icon
            appIcon = System.Drawing.Icon.ExtractAssociatedIcon(file)
            imageList.Images.Add(appIcon.ToBitmap())

            Dim fileName As String
            fileName = System.IO.Path.GetFileName(file)
            ' リストビューアイテム作成
            Dim item As ListViewItem = New ListViewItem(fileName)

            Me.ListView1.Items.Add(item)
            Me.ListView1.Items(idx).ImageIndex = idx

            idx += 1
        Next


    End Sub

    Private Sub ListView1_DrawItem(ByVal sender As Object, ByVal e As System.Windows.Forms.DrawListViewItemEventArgs) Handles ListView1.DrawItem
        Dim g As Graphics
        g = e.Graphics
        Dim drawString As String
        Dim drawString2 As String
        drawString = "AAA" + vbCrLf + "BBB"
        drawString2 = "CCC" + e.ItemIndex.ToString

        Dim rect As Rectangle
        rect = e.Bounds
        '背景描画
        If e.Item.Selected = True Then
            g.FillRectangle(Brushes.SkyBlue, rect)
        Else
            g.FillRectangle(Brushes.Yellow, rect)
        End If
        '罫線の描画
        Using pen As New Pen(Color.Gray)
            g.DrawRectangle(pen, rect)
        End Using
        '文字の描画位置
        rect.Location = New Point(e.Bounds.Left + e.Item.ImageList.Images(e.ItemIndex).Width, e.Bounds.Top)
        '文字を書く
        g.DrawString(drawString, Me.ListView1.Font, Brushes.Black, rect)

        Dim stringSize As SizeF = g.MeasureString(drawString, Me.ListView1.Font)
        '文字を書く
        g.DrawString(drawString2, Me.ListView1.Font, Brushes.Red, rect.Location.X, rect.Location.Y + stringSize.Height)

        g.DrawImage(e.Item.ImageList.Images(e.ItemIndex), e.Bounds.Location)
    End Sub

End Class

id:halohalolin

heke2meeさん大変ありがとうございます。

ListViewもやればできる子なんですね(ずいぶんコードが必要ですけど)。 

試してみましたところ、ヘッダー部分の表示がおかしかったので

Private Sub ListView1_DrawColumnHeader(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DrawListViewColumnHeaderEventArgs) Handles ListView1.DrawColumnHeader

e.DrawDefault = True

End Sub

という表示を付け加えて対応しました。

あと、選択色がBrushes.SkyBlue、非選択色がBrushes.Yellowになっていますが、ここは何とかシステムカラーでできないか調べてみます。

2011/06/27 10:40:22
  • id:halohalolin
    私の調べでは、1~3までは「C# List View v1.3」を使えば、それっぽい物が実装できそうに感じました。
    http://www.codeproject.com/KB/list/aa_listview.aspx

    標準でないコントロールを使うのは初めてなので

    Visual Basic 初級講座:第24回 標準でないコントロール
    http://homepage1.nifty.com/rucio/main/dotnet/shokyu/standard24.htm

    上記を参考に、VB2008からGlacialListをFormに組み込んでみましたが、ビルド後、起動時に以下の例外が発生し、お手上げ状態になっています。

    System.InvalidOperationException はハンドルされませんでした。
    Message="フォームの作成中にエラーが発生しました。詳細については、Exception.InnerException を参照してください。エラー: ファイルまたはアセンブリ 'GlacialList, Version=1.0.1513.31776, Culture=neutral, PublicKeyToken=null'、またはその依存関係の 1 つが読み込めませんでした。指定されたファイルが見つかりません。

    詳しい方よろしくお願いします。
  • id:halohalolin
    4.item内の文字を、部分部分で変えれるとなおよい

    修正しますorz

    4.item内の文字「色」を、部分部分で変えれるとなおよい

    よろしくお願いいたします。

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません