クリックしてハイライトするかダブルクリックしてアクションを実行できる大きなアイコン(実際には128x128以上のサムネイル)を備えたまともなスクロール可能なアイコンコントロールを必要とするWinFormsプログラムがあります。無駄なスペースを最小限に抑えることができます(各アイコンの下に短いファイル名キャプションが必要になる場合があります。ファイル名が長すぎる場合は、省略記号を追加できます)。
(ソース: pdike.org )
LargeIcon(デフォルトの.View)でListViewを使用してみましたが、結果は期待はずれです。
(ソース: 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++;
}
恥ずかしいほど小さいアイコンのある大きな空きスペースではなく、小さな空きスペースのある大きなアイコンが必要です。
私は OwnerDrawについてのこのチュートリアル を見つけましたが、そのデモは詳細ビューで行をスパイスアップする方法を示しているだけなので、基本的に上記の3または4になります。
行を追加する
ilist.ImageSize = new Size(128, 128);
forループの前にサイズの問題が修正されましたが、画像が24bpp System.Drawing.BitmapとしてImageListに挿入されていることがデバッガーに示されていても、画像は8ビットにパレット化されます(システムカラーのように見えますか?):
(ソース: pdike.org )
行を追加するとともに
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プロパティなど)を持っているかもしれませんが、最終的にそれを飼いならすことができてうれしいです:
(ソース: 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();
}
更新の場合:
FlowLayoutPanelを使用して、ピクチャボックスをドロップできます。 pictureboxを128x128のサイズに設定し、sizemodeを 'zoom'に設定します(これにより、アスペクト比を損なうことなく画像のサイズを変更できます)。プログラムでピクチャーボックスを追加することもできます。
PictureBox pb = New Picturebox;
pb.image = gcf.image128;
FlowLayoutPanel1.Controls.Add(pb)
ピクチャボックスの下にラベルを付ける必要があるため、Pastorはピクチャボックスとその下のラベルだけを持っていると言ったようなユーザーコントロールを作成できます。次に、それがflowlayoutpanelに追加するコントロールインスタンスになります。
ObjectListView (.NET ListViewのオープンソースラッパー)を使用すると、タイルビューを簡単にカスタム描画できます。デモの複雑なビューを見て、カスタム描画が有効になったらタイルビューに切り替えます。
(ソース: sourceforge.net )
128x128の画像とテキストの詳細のみが必要な場合は、所有者が描画する必要さえありません。大きな画像リストを指定し、IsTileViewColumnを使用して、タイルに表示するテキスト情報のビットをマークできます。
免責事項:私はアタラソフトで働いています
.NET Imaging SDKには画像サムネイルコントロールがあります DotImage
カスタムコントロールの作成はそれほど悪くはありません。どちらもコンテンツに自動的にスクロールバーを追加すると信じているので、PanelまたはUsercontrolを継承します。
コンテナ(PictureBoxesなど)とキャプションを動的に追加し、コンテナのmousedownイベントまたはmouseclickイベントを処理し、おそらく選択されたことを示すために周囲に赤い正方形を描画します。 「最も難しい」部分は、画像が既にそのサイズになっておらず、GDI +で簡単にできる場合でも、画像を128x128にリサンプリングします。