Перейти к содержанию
Fire Monkey от А до Я
  • 0

Собственный TListBoxItem на C++


Axbor

Вопрос

Очень не хватает примеров на C++. Решил поделится опытом.

Рассмотрим создание собственного "ListBoxItem"а на C++.

И так начнем.

Для начало создадим стиль для нашего "ListItem"а. В моем случае оно выглядит так:

post-1434-0-35990000-1454700951.png

Структура выглядеть следующим образом:

post-1434-0-95824600-1454700965.png

А вы сразу можете создать собственный стиль.

Создадим класс для нашего "Item"а. Я назвал его TMyListBoxItem.

Нужно знать следующие вещи:

ApplyStyle() вызывается когда стиль загружен.

FreeStyle() когда стиль выгружен.

GetDefaultStyleLookupName() когда стиль не задано берется названые стиля по умолчанию.

FindStyleResource("стиль") ищет в стиле ресурс с заданным названием.

 

ListBox автоматически очищает из невидимых "Item"ов стиль что бы избежать от расходы на память. И заново загружает когда оно видимо. При этом вызывается соответствующие функции приведенные выше

 

я приведу только некоторые кусочки кода. Остальное всё можете посмотреть в прикреплённых файлах.

class TMyListBoxItem : public TListBoxItem
{
private:
        // Переменные для хранения данных
	System::UnicodeString FTimeTo;
	System::UnicodeString FTimeFrom;
        //....

        // Визуальные компоненты
	TText* FTextTimeTo;
	TText* FTextTimeFrom;
        //...

        // Функции для присваивания данных, это нужно при написании "properties"
	void __fastcall SetTimeTo(const System::UnicodeString Value);
	void __fastcall SetTimeFrom(const System::UnicodeString Value);
protected:
	void __fastcall ApplyStyle();
	void __fastcall FreeStyle();
	System::UnicodeString __fastcall GetDefaultStyleLookupName();
	virtual void UpdateStyleData();
__published:
	__property System::UnicodeString TimeTo = {read=FTimeTo, write=SetTimeTo};
	__property System::UnicodeString TimeFrom = {read=FTimeFrom, write=SetTimeFrom};
public:
	__fastcall TMyListBoxItem(System::Classes::TComponent* AOwner);
};

Теперь напишем сами функции.

void __fastcall TMyListBoxItem::ApplyStyle()
{
       // Вызов метода предка
	TListBoxItem::ApplyStyle();
	TFmxObject *StyleObject;
    // Поиск ресурса из стиля. Посмотрите в скрине, там есть ресурс с названием "timeto" типа TText
	StyleObject = FindStyleResource("timeto");

       // dynamic_cast нужен для корректного преобразования типов. Если тип найденного ресурса не является TText то указателю будет присвоен NULL
	FTextTimeTo = dynamic_cast<TText*>(StyleObject);

	StyleObject = FindStyleResource("timefrom");
	FTextTimeFrom = dynamic_cast<TText*>(StyleObject);

	UpdateStyleData();
}

void __fastcall TMyListBoxItem::FreeStyle()
{
       // Стиль выгружен из памяти. Нужно очистить указатели что бы избежать ошибок
	FTextTimeTo = NULL;
	FTextTimeFrom = NULL;

	TListBoxItem::FreeStyle();
}

System::UnicodeString __fastcall TMyListBoxItem::GetDefaultStyleLookupName()
{
    // название стиля для нашего "Item"а по умолчанию
	return "mylistboxitemstyle";
}

void TMyListBoxItem::UpdateStyleData()
{
	if(FTextTimeTo)
		FTextTimeTo->Text = FTimeTo;
	if(FTextTimeFrom)
		FTextTimeFrom->Text = FTimeFrom;
}

void __fastcall TMyListBoxItem::SetTimeTo(const System::UnicodeString Value)
{
	FTimeTo = Value;
	if(FTextTimeTo)
		FTextTimeTo->Text = FTimeTo;
}

Вот и всё. Остается только добавит в наш проект ListBox и button для проверки.

Вот функция создания нашего "Item"а:

void __fastcall TForm1::Button1Click(TObject *Sender)
{
	TMyListBoxItem *Item = new TMyListBoxItem(this);
	Item->Parent = ListBox1;
	Item->StyleLookup = "customstyle1";
	Item->TimeFrom = "11:20";
	Item->TimeTo = "12:50";
}

Скриншот программы:

post-1434-0-12060700-1454703141_thumb.pn

В архиве мой класс и стиль. Для корректного отображения некоторых символов нужен fontcustom

Какие вопросы задавайте. Отдельное спасибо Ярославу за мануал на дельфи: 

http://blogs.embarcadero.com/yaroslavbrovin/2012/10/15/listboxitem_styling_part2/

Администраторы и модераторы, прошу подкорректировать если что то неправильно.

ListBoxItem.zip

Изменено пользователем Axbor
Ссылка на комментарий

Рекомендуемые сообщения

  • 0
  • Модераторы

имхо можно это же оформить процедурно для ListItem

даже можно свой класс создать для удобства, кстати вылетело из головы. через адаптеры если не ошибаюсь

Ссылка на комментарий
  • 0

Добрый день.  Может быть кто-то подскажет: айтемы создаются без соблюдения размеров стиля. То есть все поля съезжаются в кучу и толщина айтема равна стандартной. КТо-нибудь сталкивался? 

Ссылка на комментарий
  • 0
  • Администраторы

При применении стиль всегда растягивается по размеру контрола, а не наоборот. Если вы хотите, чтобы у вас всегда был фиксированный размер, то в стиле используйте FixedWidth, FixedHeight.

Если вы не хотите фиксировать размер итема, а лишь задать дефолтный размер, то переопределите в классе итема метод GetDefaultSize, в котором верните желаемый размер.

Ссылка на комментарий

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить на вопрос...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...