Оригинальный вопрос (см. Обновление ниже)
У меня есть программа WinForms, которая нуждается в приличном прокручиваемом элементе управления значками с большими значками (на самом деле размером 128x128 или больше), которые можно щелкнуть до полусвета или дважды щелкнуть, чтобы выполнить какое-либо действие. Предпочтительно, чтобы было минимальное потраченное впустую пространство (под каждым значком могут понадобиться короткие заголовки имен файлов; если имя файла слишком длинное, я могу добавить многоточие).
(источник: updike.org )
Я попытался использовать ListView с LargeIcon (по умолчанию .View), и результаты разочаровывают:
(источник: updike.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++;
}
Мне нужны большие значки с небольшим пустым пространством, а не большое пустое пространство с смущающе маленькими значками.
- Есть ли элемент управления .NET, который делает то, что мне нужно?
- Есть ли любимый сторонний элемент управления, который делает это?
- Если нет, какой элемент управления лучше всего унаследовать и настроить для его работы?
- Должен ли я сломаться и создать собственный элемент управления (с которым у меня большой опыт ... просто не хочу переходить к этому крайнему виду, так как это несколько связано).
Я нашел этот урок о OwnerDraw , но работа с ним в основном составляет 3 или 4 выше, поскольку эта демонстрация просто показывает, как оживить строки в подробном представлении.
Обновление
Добавление строки
ilist.ImageSize = new Size(128, 128);
до того, как цикл for устранил проблему размера, но теперь изображения палитрированы до 8-битных (выглядит как системные цвета?), Хотя отладчик показывает, что изображения вставляются в ImageList как 24bpp System.Drawing.Bitmap's :
(источник: updike.org )
- Как я могу (могу ли я?) Заставить изображения отображаться в полном 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), но я рад, что мог бы приручить его, в конце концов:
(источник: updike.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();
}