C++ Builder
| Главная | Уроки | Статьи | FAQ | Форум | Downloads | Литература | Ссылки | RXLib | Диски |

 
Выделение строк в DBGridEh, по критерию Item RxCheckListBox1
laifik
  Отправлено: 20.01.2005, 10:16


Дежурный стрелочник

Группа: Участник
Сообщений: 70



Что-то не получается у меня совместить нажатие на RxCheckListBox1 и выделение строк в Гриде.
Но по порядку.
1 часть. У меня работает такой код:
CODE
void __fastcall TForm1::DBGridEh2DrawColumnCell(TObject *Sender,
     const TRect &Rect, int DataCol, TColumnEh *Column,
     TGridDrawState State)
{
AnsiString TR;
TR = "01";
 TDBGridEh *  Eh_Oper = (TDBGridEh *)Sender;

     if( !State.Contains(gdSelected) && ( Eh_Oper->DataSource->DataSet->FieldByName("GostID")->AsString.Trim() == TR)) {

     Eh_Oper->Canvas->Brush->Color = TColor(0x00C6FFFF);
     Eh_Oper->Canvas->FillRect(Rect);
     Eh_Oper->Canvas->TextOut(Rect.Left+2,Rect.Top+2,Column->Field->Text);
Eh_Oper->DefaultDrawColumnCell(Rect,DataCol,Column,State);
        }

Выделяется строка, где в поле GostID есть значение "01". Как задать переменную TR, чтобы выделялись все строки, значения rкоторых в поле начинались на "01".
2 часть: Переменная TR должна определиться в событии OnClickCheck компонента RxCheckListBox1
CODE
TR = RxCheckListBox1->Items->Strings[RxCheckListBox1->ItemIndex];

Но событие DBGridEh2DrawColumnCell наступает раньше, чем событие OnClickCheck. Как сделать, чтобы выделение записей происходило только после нажатия на Item RxCheckListBox1?
laifik
Отправлено: 20.01.2005, 13:10


Дежурный стрелочник

Группа: Участник
Сообщений: 70



1 часть решила. Нужен ответ по второй части.
trigger
Отправлено: 20.01.2005, 13:35


Не зарегистрирован







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

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

тогда зачем в обработчике DBGridEh2DrawColumnCell явно выставляется
TR = "01";
?
значение "01" присутствует в списке лист бокса? тада может выставить его программно в листбоксе, а потом по событии выбора вызовется сам DBGridEh2DrawColumnCell и все ништь ... не?

и не будет ли пролемы с тем что переменная TR объявляется внутри блока DBGridEh2DrawColumnCell, а достучаться до нее вы хоите из другого места проги..?

или я где туплю..?
laifik
Отправлено: 20.01.2005, 13:48


Дежурный стрелочник

Группа: Участник
Сообщений: 70



2. Логику правильно поняли. Именно так.
QUOTE
тогда зачем в обработчике DBGridEh2DrawColumnCell явно выставляется
TR = "01";

Просто я отрабатывала эту часть отдельно. Она у меня не работала, поэтому переменную задала конкретно.
Код работающий таков:
CODE

void __fastcall TForm1::DBGridEh2DrawColumnCell(TObject *Sender,
     const TRect &Rect, int DataCol, TColumnEh *Column,
     TGridDrawState State)
{
AnsiString TR;
TR = "01";
 // if( !lbSelected && State.Contains(gdSelected) ) {
 TDBGridEh *  Eh_Oper = (TDBGridEh *)Sender;

     if( !State.Contains(gdSelected) && ( Eh_Oper->DataSource->DataSet->FieldByName("GostID")->AsString.Trim().SubString(1,2) == TR)) {

     Eh_Oper->Canvas->Brush->Color = TColor(0x00C6FFFF);
     Eh_Oper->Canvas->FillRect(Rect);
     Eh_Oper->Canvas->TextOut(Rect.Left+2,Rect.Top+2,Column->Field->Text);
Eh_Oper->DefaultDrawColumnCell(Rect,DataCol,Column,State);
        }
}

Вся проблема в том, что событие DBGridEh2DrawColumnCell начинает отрабатываться в момент открытия формы с Гридом. А мне нужно, чтобы оно отрабатывалось в момент нажатия на чекбокс, где определялась переменная TR, которая и передавалась бы в событие OnDrawColumnCell.
Переменную я объявляю не внутри блока, а в private:
Есть еще одно событие Грида:
QUOTE
Вы можете изменить цвет шрифта и фона ячейки таблицы (либо ее строки или столбца) в зависимости от значения поля, определив обработчик события OnGetCellParams;

Но я не нашла примера кода, как пользоваться событием.
trigger
Отправлено: 20.01.2005, 14:45


Не зарегистрирован







QUOTE
1 часть. У меня работает такой код:
CODE:
void __fastcall TForm1::DBGridEh2DrawColumnCell(TObject *Sender,
    const TRect &Rect, int DataCol, TColumnEh *Column,
    TGridDrawState State)
{
AnsiString TR;
TR = "01";

QUOTE
Переменную я объявляю не внутри блока, а в private:


я не поянл, первый кусок кода — он всеже уже ваш рабочий, или это всеже пример...
там ведь явно задается AnsiString TR; и TR = "01";
на да ладно с ним...

а если такой алгоритм:

1.при создании формы: переменная TR = "01";
2. прорисовывается грид, где используется переменная ТР
3. в итоге выделены нужные значения...

после создания формы:
1. кликаем по листбоксу и выбераем значение.
2.в обраотчике листбокса он_клик:
- ТР = выбранное значение листокса
- вызываем метод DBGridEh2->Refresh(); а он в свою очередь вызовет DBGridEh2DrawColumnCell и выделяться новые ячейки...
а если не вызовет, то переоткрыть датасет... он то точно вызовет перерисовку грида...

не прокатит так?
laifik
Отправлено: 20.01.2005, 14:57


Дежурный стрелочник

Группа: Участник
Сообщений: 70



Полный код таков:
в файле .h
CODE

private: // User declarations
String TR;

CODE

void __fastcall TForm1::RxCheckListBox1ClickCheck(TObject *Sender)
{
TR = RxCheckListBox1->Items->Strings[RxCheckListBox1->ItemIndex];
DBGridEh2->OnDrawColumnCell =  DBGridEh2DrawColumnCell;
}

Далее
CODE
void __fastcall TForm1::DBGridEh2DrawColumnCell(TObject *Sender,
     const TRect &Rect, int DataCol, TColumnEh *Column,
     TGridDrawState State)
{
 TDBGridEh *  Eh_Oper = (TDBGridEh *)Sender;

     if( !State.Contains(gdSelected) && ( Eh_Oper->DataSource->DataSet->FieldByName("GostID")->AsString.Trim().SubString(1,2) == TR)) {

     Eh_Oper->Canvas->Brush->Color = TColor(0x00C6FFFF);
     Eh_Oper->Canvas->FillRect(Rect);
     Eh_Oper->Canvas->TextOut(Rect.Left+2,Rect.Top+2,Column->Field->Text);
Eh_Oper->DefaultDrawColumnCell(Rect,DataCol,Column,State);
        }  }


QUOTE
вызываем метод DBGridEh2->Refresh(); а он в свою очередь вызовет DBGridEh2DrawColumnCell и выделяться новые ячейки...
а если не вызовет, то переоткрыть датасет... он то точно вызовет перерисовку грида...

Вот этого я добиваюсь. Но не знаю, как из события RxCheckListBox1ClickCheck вызвать DBGridEh2DrawColumnCell . Не подскажите?
TRIGGER
Отправлено: 20.01.2005, 15:22


Не зарегистрирован







QUOTE
Вот этого я добиваюсь. Но не знаю, как из события RxCheckListBox1ClickCheck вызвать DBGridEh2DrawColumnCell . Не подскажите?

)) АХ "ВОТ ГДЕ СОБАКА ПОРЫЛАСЬ..."

я щас у себя проверил. у меня
функция DBGridEh2->Refresh();
вызывает метод DBGridEh2DrawColumnCell
вроде как для всех ячеек...

laifik
Отправлено: 20.01.2005, 16:33


Дежурный стрелочник

Группа: Участник
Сообщений: 70



Я все-таки сделала по-другому:
CODE
void __fastcall TForm1::RxCheckListBox1ClickCheck(TObject *Sender)
{
if( RxCheckListBox1->ItemIndex != -1 ){    //"selected, checked"
   if( RxCheckListBox1->Checked[ RxCheckListBox1->ItemIndex ] ){

TR = RxCheckListBox1->Items->Strings[RxCheckListBox1->ItemIndex];
DBGridEh2->OnGetCellParams =  DBGridEh2GetCellParams;
DBGridEh2->Refresh();
   }
}
и второе событие
CODE
void __fastcall TForm1::DBGridEh2GetCellParams(TObject *Sender,
     TColumnEh *Column, TFont *AFont, TColor &Background,
     TGridDrawState State)
{
TDBGridEh *  Eh_Oper = (TDBGridEh *)Sender;
     if(Eh_Oper->DataSource->DataSet->FieldByName("GostID")->AsString.Trim().SubString(1,2) == TR)
   {
if( RxCheckListBox1->ItemIndex != -1 ){    //"selected, checked"
   if( RxCheckListBox1->Checked[ RxCheckListBox1->ItemIndex ] ){
           AFont->Color = clRed;
           Background = TColor(0x00C6FFFF);
   }else{   //"selected, not checked"
           AFont->Color = clBlack;
           Background = clWhite;
                }
          }
   }  

Все работает, кроме того, что при смене Item-а сбрасывается предыдущее выделение. Мне нужно, чтобы выделение оставалось, а новое добавлялось.
Guest
Отправлено: 20.01.2005, 16:34


Не зарегистрирован







DBGridEh2->Invalidate() или подобный метод
laifik
Отправлено: 20.01.2005, 16:47


Дежурный стрелочник

Группа: Участник
Сообщений: 70



CODE
void __fastcall TForm1::DBGridEh2GetCellParams(TObject *Sender,
     TColumnEh *Column, TFont *AFont, TColor &Background,
     TGridDrawState State)
{
if(Column->FieldName  != "GostID") return;
 for(int i = 0;i < RxCheckListBox1->Items->Count;i++)
 {
   if(RxCheckListBox1->Checked[i])
     if(Column->Field->AsString.Trim().SubString(1,2)  == RxCheckListBox1->Items->Strings[i])
     {
        AFont->Color = clRed;
        Background = TColor(0x00C6FFFF);
        break;
     }
 }  
}

Только теперь почему-то выделяет ячейки столбца. А хотелось бы целую строку.

Отредактировано laifik — 20/01/2005, 17:51
Guest
Отправлено: 20.01.2005, 17:31


Не зарегистрирован







Анализируйте значение колонки GostID текущей строки
вместо
if(Column->FieldName != "GostID") return;
... for(int i = 0;i < RxCheckListBox1->Items->Count;i++)
if(Column->Field->AsString.Trim().SubString(1,2) == RxCheckListBox1->Items-

использовать
if (DataSet->FieldByName("GostID")->AsString.Trim().SubString(1,2) == RxCheckListBox1->Items->Strings[i])
** laifik
Отправлено: 20.01.2005, 19:54


Не зарегистрирован







Я уже догадалась. Вот работающий код:
CODE
void __fastcall TForm1::DBGridEh2GetCellParams(TObject *Sender,
     TColumnEh *Column, TFont *AFont, TColor &Background,
     TGridDrawState State)
{
TDBGridEh *  Eh_Oper = (TDBGridEh *)Sender;
 for(int i = 0;i < RxCheckListBox1->Items->Count;i++)
 {
   if(RxCheckListBox1->Checked[i])
       if(Eh_Oper->DataSource->DataSet->FieldByName("GostID")->AsString.Trim().SubString(1,2) == RxCheckListBox1->Items->Strings[i])
     {
        AFont->Color = clRed;
        Background = TColor(0x00C6FFFF);
        break;
     }
 }  
}

Огромное спасибо за помощь! smile.gif

Вернуться в Вопросы программирования в C++Builder