web-dev-qa-db-ja.com

ListViewのグリッドに128x128ピクセル以上のサムネイルアイコンを表示する

元の質問(下記の更新を参照)

クリックしてハイライトするかダブルクリックしてアクションを実行できる大きなアイコン(実際には128x128以上のサムネイル)を備えたまともなスクロール可能なアイコンコントロールを必要とするWinFormsプログラムがあります。無駄なスペースを最小限に抑えることができます(各アイコンの下に短いファイル名キャプションが必要になる場合があります。ファイル名が長すぎる場合は、省略記号を追加できます)。

finished version of listview with proper colors, spacing, etc.
(ソース: pdike.org

LargeIcon(デフォルトの.View)でListViewを使用してみましたが、結果は期待はずれです。

screenshot showing tiny icons in LargeIcon view
(ソース: pdike.org

おそらく、コントロールを誤って設定していますか?コード:

        ImageList ilist = new ImageList();
        this.listView.LargeImageList = ilist;
        int i = 0;
        foreach (GradorCacheFile gcf in gc.files)
        {
            Bitmap b = gcf.image128;
            ilist.Images.Add(b);
            ListViewItem lvi = new ListViewItem("text");
            lvi.ImageIndex = i;
            this.listView.Items.Add(lvi);
            i++;
        }

恥ずかしいほど小さいアイコンのある大きな空きスペースではなく、小さな空きスペースのある大きなアイコンが必要です。

  1. 必要なことを行う.NETコントロールはありますか?
    • これを行うお気に入りのサードパーティコントロールはありますか?
    • そうでない場合、どのコントロールを継承し、それを機能させるために微調整するのが最適でしょうか?
    • 分解してカスタムコントロールを作成する必要があります(これには十分な経験があります...多少複雑なので、極端なことはしたくないです)。

私は OwnerDrawについてのこのチュートリアル を見つけましたが、そのデモは詳細ビューで行をスパイスアップする方法を示しているだけなので、基本的に上記の3または4になります。

更新

行を追加する

ilist.ImageSize = new Size(128, 128);

forループの前にサイズの問題が修正されましたが、画像が24bpp System.Drawing.BitmapとしてImageListに挿入されていることがデバッガーに示されていても、画像は8ビットにパレット化されます(システムカラーのように見えますか?):

large icons, finally
(ソース: pdike.org

  1. 画像を完全な24ビットカラーで表示するには(どうすればよいですか)。
    • アイコンの周りの間隔はまだかなり無駄です...どうすれば修正できますか?できますか?

更新2

行を追加するとともに

ilist.ColorDepth = ColorDepth.Depth24Bit;

次にilist.ImageSizeを設定した後、アービターのアドバイスに従い、間隔を変更しました。

[DllImport("user32.dll")]
public static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);

public int MakeLong(short lowPart, short highPart)
{
    return (int)(((ushort)lowPart) | (uint)(highPart << 16));
}

public void ListView_SetSpacing(ListView listview, short cx, short cy)
{
    const int LVM_FIRST = 0x1000;
    const int LVM_SETICONSPACING = LVM_FIRST + 53;
    // http://msdn.Microsoft.com/en-us/library/bb761176(VS.85).aspx
    // minimum spacing = 4
    SendMessage(listview.Handle, LVM_SETICONSPACING,
    IntPtr.Zero, (IntPtr)MakeLong(cx, cy));

    // http://msdn.Microsoft.com/en-us/library/bb775085(VS.85).aspx
    // DOESN'T WORK!
    // can't find ListView_SetIconSpacing in dll comctl32.dll
    //ListView_SetIconSpacing(listView.Handle, 5, 5);
}

///////////////////////////////////////////////////////////

ListView_SetSpacing(this.listView, 128 + 12, 128 + 4 + 20);

ListViewコントロールは完璧ではないかもしれませんし、私が期待するデフォルト(Spacingプロパティなど)を持っているかもしれませんが、最終的にそれを飼いならすことができてうれしいです:

alt text
(ソース: pdike.org

ちなみに、サムネイルの適切なアスペクト比を維持するには、独自の128x128ビットマップを作成し、コントロールに合わせて背景をクリアし、それらの画像を中央に配置する必要がありました。

public void CenterDrawImage(Bitmap target, Color background, Bitmap centerme)
{
    Graphics g = Graphics.FromImage(target);
    g.Clear(background);
    int x = (target.Width - centerme.Width) / 2;
    int y = (target.Height - centerme.Height) / 2;
    g.DrawImage(centerme, x, y);
    g.Dispose();
}
44
Jared Updike

更新の場合:

  1. 画像サイズに加えて画像リストの色深度を設定します(ilist.ColorDepth = ColorDepth.Depth24Bit)
  2. WinForms ListViewはアイコンの間隔を変更する可能性はありませんが、Win32を使用して簡単に行うことができます。 ListViewに LVM_SETICONSPACING を送信する必要があります(.netでSendMessage win32関数を使用する方法は多くのチュートリアルがあるため、この方向で十分だと思います)。
13
arbiter

FlowLayoutPanelを使用して、ピクチャボックスをドロップできます。 pictureboxを128x128のサイズに設定し、sizemodeを 'zoom'に設定します(これにより、アスペクト比を損なうことなく画像のサイズを変更できます)。プログラムでピクチャーボックスを追加することもできます。

PictureBox pb = New Picturebox;
 pb.image = gcf.image128;
 FlowLayoutPanel1.Controls.Add(pb)

ピクチャボックスの下にラベルを付ける必要があるため、Pastorはピクチャボックスとその下のラベルだけを持っていると言ったようなユーザーコントロールを作成できます。次に、それがflowlayoutpanelに追加するコントロールインスタンスになります。

5
jvanderh

ObjectListView (.NET ListViewのオープンソースラッパー)を使用すると、タイルビューを簡単にカスタム描画できます。デモの複雑なビューを見て、カスタム描画が有効になったらタイルビューに切り替えます。 owner drawn tile view
(ソース: sourceforge.net

128x128の画像とテキストの詳細のみが必要な場合は、所有者が描画する必要さえありません。大きな画像リストを指定し、IsTileViewColumnを使用して、タイルに表示するテキスト情報のビットをマークできます。

5
Grammarian

免責事項:私はアタラソフトで働いています

.NET Imaging SDKには画像サムネイルコントロールがあります DotImage

2
Lou Franco

カスタムコントロールの作成はそれほど悪くはありません。どちらもコンテンツに自動的にスクロールバーを追加すると信じているので、PanelまたはUsercontrolを継承します。

コンテナ(PictureBoxesなど)とキャプションを動的に追加し、コンテナのmousedownイベントまたはmouseclickイベントを処理し、おそらく選択されたことを示すために周囲に赤い正方形を描画します。 「最も難しい」部分は、画像が既にそのサイズになっておらず、GDI +で簡単にできる場合でも、画像を128x128にリサンプリングします。

1
Pastor