Форум: "Прочее";
Текущий архив: 2011.09.04;
Скачать: [xml.tar.bz2];
Внизотрисовка Items в tlistbox Найти похожие ветки
← →
stay unknown (2011-05-12 15:57) [0]Нужно рисовать айтемы листбокса.
Кажды айтем должен получится вида:
Тип: Телевизор ЖК \ ТВ
Производитель: Samsung
Модель: UE37C6540SW
Слева еще иконка товара будет. Вопрос: как лучше организовать отрисовку:
- написать функцию, что-то типа:
function DrawBlockProductDescription(Canvas: TCanvas; X, Y: Int; Margins: TMargins; Bitmap: TBitmap): TRect;
- написать класс.
Что посоветуете?
← →
Kerk © (2011-05-12 15:58) [1]Да функции хватит. Зачем тут целый класс.
← →
b z (2011-05-12 16:02) [2]
> Что посоветуете?
ListView
← →
Лукошко (2011-05-12 16:31) [3]Есс-но, это - простой пример на скорую руку, сделай нормально.
Класс товара:
type
TItem=class
public
tp:string;
ds:string;
md:string;
end;
В коде:
{заполнение листбокса товаром}
procedure TForm1.Button1Click(Sender:TObject);
var
i:integer;
item:TItem;
begin
for i:=1 to 10 do begin
item:=TItem.Create;
item.tp:="Тип продукции: "+IntToStr(i)+" DFG";
item.ds:="Производитель продукции: "+IntToStr(i)+" manufacture";
item.md:="Модель: "+IntToStr(i)+" serial";
ListBox1.AddItem(item.tp,item);
end;
end;
{отрисовка}
procedure TForm1.ListBox1DrawItem(Control:TWinControl; Index:Integer; Rect:TRect; State:TOwnerDrawState);
var
LoadIndex:integer;
Bitmap:TBitmap;
BMPRect:TRect;
ColorRect:TRect;
begin
with TListBox(Control),Canvas do begin
{выделяем выделение :o)}
if odSelected in State then Brush.Color:=$00FAEADC
else Brush.Color:=clWindow;
FillRect(Rect);
{рисуем разделители}
Pen.Style:=psDot;
Pen.Color:=clGray;
MoveTo(128,Rect.Top);
LineTo(128,Rect.Bottom);
MoveTo(Rect.Left,Rect.Bottom-1);
LineTo(Rect.Right,Rect.Bottom-1);
{левая строка}
Font.Color:=clNavy;
Font.Size:=8;
Font.Style:=[fsBold];
TextOut(Rect.Left+20,Rect.Top+2,TItem(Items.Objects[index]).md);
{верхняя строка}
Font.Color:=clBlack;
Font.Size:=8;
Font.Style:=[fsBold];
TextOut(Rect.Left+150,Rect.Top+2,TItem(Items.Objects[index]).tp);
{нижняя строка}
Font.Color:=clMaroon;
Font.Size:=7;
Font.Style:=[];
TextOut(Rect.Left+166,Rect.Top+17,TItem(Items.Objects[index]).ds);
{убираем рамку}
if odFocused in State then DrawFocusRect(Rect);
end;
end;
← →
Лукошко (2011-05-12 16:37) [4]Рисовка иконки из иконлиста:
BlaBlaImageList.Draw(TListBox(Control).Canvas,10,Rect.Top+5,IconIndex,true);
Рисовка иконки из битмапа:
{рисуем иконку}
var
Bitmap:TBitmap;
BMPRect:TRect;
begin
Bitmap:=TBitmap.Create;
try
Bitmap.LoadFromFile({путь к файлу, к примеру});
if Bitmap<>nil then begin
BMPRect:=Bounds(36,Rect.Top+7,16,16);
BrushCopy(BMPRect,Bitmap,Bounds(0,0,Bitmap.Width,Bitmap.Height),Bitmap.Canvas.Pi xels[15,0]);
end;
finally
Bitmap.Free;
end;
end;
← →
Лукошко (2011-05-12 16:39) [5]У листбокса должен быть style=lbOwnerDrawVariable или lbOwnerDrawFixed.
Первый - для разных по высоте итемов, если мне не изменяет память.
← →
KilkennyCat © (2011-05-12 17:12) [6]
> type
> TItem=class
> public
> tp:string;
> ds:string;
> md:string;
> end;
>
из пушки по воробьям.
← →
clickmaker © (2011-05-12 17:39) [7]> из пушки по воробьям
почему? У него же реальный объект "Телевизор" с параметрами, как раз тянет на класс
← →
Лукошко (2011-05-12 17:45) [8]
> KilkennyCat © (12.05.11 17:12) [6]
Так удобнее же.
Хотя можно и рекорд, и вообще строку с разделителями :o)
← →
stay unknown (2011-05-12 18:05) [9]с отрисовкой разобрался, теперь сложность в другом. айтем может быть 3 видов:
Тип: Телевизор ЖК \ ТВ
Производитель: Samsung
Модель: UE37C6540SW
Тип: не найден (<ID типа>)
Модель: не найдена (<ID модели>)
Размер айтема напрямую зависит от высоты блока рисуемой информации в событии OnDrawItem. Как динамически менять его размер. Знаю что размер можно менять в OnMeasureItem, но как из события узнать высоту нарисованного блока.
← →
clickmaker © (2011-05-12 18:09) [10]> как из события узнать высоту нарисованного блока
Canvas.TextHeight
← →
stay unknown (2011-05-12 18:27) [11]Я про другое
у меня размер блока выводимой информации рассчитывается на момент отрисовки (не для всех Items он одинаковый). Сам блок представляет собой несколько TextOut"ов разделенных между собой.
Все возможные варианты.
(1)
Тип: Телевизор ЖК \ ТВ
Производитель: Samsung
Модель: UE37C6540SW
(2)
Тип: Телевизор ЖК \ ТВ
Производитель: Samsung
(3)
Производитель: Samsung
Модель: UE37C6540SW
(4)
Тип: Телевизор ЖК \ ТВ
Модель: UE37C6540SW
(5)
Тип: Телевизор ЖК \ ТВ
(6)
Производитель: Samsung
(7)
Модель: UE37C6540SW
Блок 1 - одного размера, 2, 3, 4 - другого, 5,6,7 - третьего
Как из OnMeasureItem получить высоту отрисованного блока для I-ого айтема
← →
KilkennyCat © (2011-05-12 18:32) [12]
> clickmaker © (12.05.11 17:39) [7]
потому, что тут достаточно
> Лукошко (12.05.11 17:45) [8]
как-то привык, что в переменных хранятся данные того же типа, что и переменная (а не использование, например, строковых для чисел). Это удобно. При виде класса я буду предполагать наличие гораздо большего, чем пара переменных.
← →
Игорь Шевченко © (2011-05-12 18:34) [13]
> Как из OnMeasureItem получить высоту отрисованного блока
> для I-ого айтема
item же передается, по нему и вычислить
← →
KilkennyCat © (2011-05-12 18:35) [14]
> Как из OnMeasureItem получить высоту отрисованного блока
> для I-ого айтема
высчитать сразу при отрисовке.
← →
Лукошко (2011-05-12 18:46) [15]Меняем условие:
{заполнение листбокса товаром}
procedure TForm1.Button1Click(Sender: TObject);
var
i:integer;
item:TItem;
begin
for i:=1 to 10 do begin
item:=TItem.Create;
item.tp:="Тип продукции: "+IntToStr(i)+" DFG";
if (i mod 2)=0 then item.ds:="Производитель продукции: "+IntToStr(i)+" manufacture"
else item.ds:="";
item.md:="Модель: "+IntToStr(i)+" serial";
ListBox1.AddItem(item.ds,item); //обрати внимание - передаю другой итем
end;
end;
Вычисление высоты:
{меняем высоту итема}
procedure TForm1.ListBox1MeasureItem(Control:TWinControl; Index:Integer; var Height:Integer);
begin
if TListBox(Control).Items[Index]="" then Height:=20;
end;
ЗЫ: Обрати внимание, объект item в AddItem добавляется ПОСЛЕ вызова MeasureItem
← →
Лукошко (2011-05-12 18:50) [16]
> KilkennyCat © (12.05.11 18:32) [12]
Ну так-то согласен, рекорд понятнее.
> Игорь Шевченко © (12.05.11 18:34) [13]
В том-то и дело, что ещё не передался Item, только после OnMeasureItem добавляется ссылка. Ну или ткните меня носом :o)
← →
clickmaker © (2011-05-12 18:58) [17]> Ну так-то согласен, рекорд понятнее
вообще, объектную модель не гуй должен диктовать. Сегодня листбокс, а завтра разноцветный суперпупергридвью какой-нить с хедерами и футерами.
← →
Игорь Шевченко © (2011-05-12 19:10) [18]
> В том-то и дело, что ещё не передался Item, только после
> OnMeasureItem добавляется ссылка. Ну или ткните меня носом
> :o)
http://msdn.microsoft.com/en-us/library/bb775925(v=vs.85).aspx
← →
Лукошко (2011-05-12 19:18) [19]
> clickmaker © (12.05.11 18:58) [17]
Дык я и не настаивал. Для данного примера вообще пофигу, как объявить, это жыж просто пример для автора топика.
> Игорь Шевченко © (12.05.11 19:10) [18]
Прочитал.
← →
Игорь Шевченко © (2011-05-12 19:24) [20]Лукошко (12.05.11 19:18) [19]
> Прочитал.
Там написано, что сообщение посылается в зависимости от стиля, если стиль с элементами фиксированной высоты, то один раз для контрола, если стиль с элементами разной высоты, то для каждого элемента.
Поэтому фраза
> только после OnMeasureItem добавляется ссылка
в этом контексте звучит слегка некорректно
← →
Лукошко (2011-05-12 19:37) [21]
> Игорь Шевченко © (12.05.11 19:24) [20]
Я понял, что там написано :o)
Да, согласен, немного не так. Ну так у автора как раз вэриэйбл высота, сообщение посылается каждый раз. Но ещё до добавления ссылки на объект в AddObject"е.
← →
Игорь Шевченко © (2011-05-12 21:16) [22]Лукошко (12.05.11 19:37) [21]
Все, сообразил.
TListBoxStrings.Add посылает LB_ADDSTRING, а Object к этому моменту еще не установлен, потому что TStrings.AddObject сначала выполняет Add, а потом PutObject
Я бы в таком случае хранил список объектов отдельно и использовал бы виртуальный ListBox
← →
Лукошко (2011-05-12 21:32) [23]
> Игорь Шевченко © (12.05.11 21:16) [22]
Я именно так и сделал, виртуальный ListBox. Вообще, не очень удобно сделано в генофонде, много лишнего надо писать.
Автор топика, думаю, может обойтись > Лукошко (12.05.11 18:46) [15]
← →
Dimka Maslov © (2011-05-12 22:13) [24]Что мешает воспользоваться компонентом TListView, у которого уже есть возможность отрисовки иконок?
← →
Германн © (2011-05-13 02:47) [25]
> Dimka Maslov © (12.05.11 22:13) [24]
>
> Что мешает воспользоваться компонентом TListView, у которого
> уже есть возможность отрисовки иконок?
>
А при чем тут "возможность отрисовки иконок"?
← →
Лукошко (2011-05-13 15:12) [26]Так вот старался-старался, писал, собирал у себя готовый код, а автор даже спасибо не сказал :o(
У вас тут все студенты неблагодарные?
← →
KilkennyCat © (2011-05-13 18:10) [27]
> Лукошко (13.05.11 15:12) [26]
настоящие герои плюют на признание толпы.
← →
Лукошко (2011-05-13 19:10) [28]
> KilkennyCat © (13.05.11 18:10) [27]
Хыхы
Мне до героя далекоооо... :o)
Страницы: 1 вся ветка
Форум: "Прочее";
Текущий архив: 2011.09.04;
Скачать: [xml.tar.bz2];
Память: 0.52 MB
Время: 0.004 c