The Unofficial Newsletter of Delphi Users - by Robert Vivrette

Множественный выбор в  String Grid

By Christian Ebenegger - c.ebenegger@fsp.ch and Thierry Revillard - thierry.revillard@fsp.ch

Перевод Руденко Е.В.   janer@newmail.ru    октябрь 2001 года

 

Давайте рассмотрим компонент  String Grid с двумя колонками, в котором мы хотим выбрать некоторые ячейки в первой колонке , используя клавишу CTRL  + мышку  для непоследовательного выбора или клавишу SHIFT  + мышку для последовательного выбора . Для того чтобы сделать это, во первых, нам необходимо создать два компонента  TStringList, для сохранения выбранных элементов :

GStringL := TStringList.Create;
Linestring := TStringList.Create;
Затем, мы должны определить событие  OnDrawCell  :
procedure TForm1.GenStringGridOnDrawCell(Sender: TObject; ACol,
  ARow: Integer; Rect: TRect; State: TGridDrawState);
var
 GString : String;
 I, TheRowHeigt : Integer;
begin
 if State = [gdFixed] then // центрирование заголовка каждой колонки
  begin
   GenStringGrid.Canvas.FillRect(Rect);
   GString := GenStringGrid.Cells[ACol,ARow];
   DrawText(GenStringGrid.Canvas.Handle,PChar(GString),StrLen(PChar(GString)),Rect,DT_CENTER);
  end;

 if ((ACol = 1) and (ARow > 0)) then // многострочный текст в ячейке
  begin
   GenStringGrid.Canvas.FillRect(Rect);
   GString := GenStringGrid.Cells[ACol,ARow];
   if GString <> '' then
    begin
     TheRowHeigt := DrawText(GenStringGrid.Canvas.Handle,PChar(GString),StrLen(PChar(GString)),Rect,
          DT_CALCRECT or DT_WORDBREAK) + 2;
     if TheRowHeigt > GenStringGrid.RowHeights[ARow] then
        GenStringGrid.RowHeights[ARow] := TheRowHeigt;
     DrawText(GenStringGrid.Canvas.Handle,PChar(GString),StrLen(PChar(GString)),
     Rect,DT_WORDBREAK);
    end;
  end;

   if ((ACol = 0) and (ARow > 0)) then
    begin
     GenStringGrid.Canvas.FillRect(Rect);
     GString := GenStringGrid.Cells[ACol,ARow];
     I := GStringL.IndexOf(GString); //если ячейка выбрана, закрашивание ее красным цветом
     if I > -1 then
      begin
       GenStringGrid.Canvas.Font.Color := clWhite;
       GenStringGrid.Canvas.Brush.Color := clRed;
      end
     else
      begin
       GenStringGrid.Canvas.Font.Color := GenStringGrid.Font.Color ;
       GenStringGrid.Canvas.Brush.Color := GenStringGrid.Color;

      end;
     GenStringGrid.Canvas.FillRect(Rect);
     DrawText(GenStringGrid.Canvas.Handle,PChar(GString),StrLen(PChar(GString)),Rect,DT_Left);
    end;
end;

Теперь при использовании CTRL + левая кнопка мыши или  SHIFT  + левая кнопка мыши, нам необходимо добавить следующий код в событие On MouseUp  :
procedure TForm1.GenStringGridOnMouseUp(Sender: TObject;
  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
 TheRow, TheCol : LongInt;
 WhichKey : Integer;
begin
 if Button = mbLeft then
  begin
   GenStringGrid.MouseToCell(X,Y,TheCol,TheRow);
   if (TheCol > -1) and (TheRow > -1) then
    begin
     if (TheCol = 0) and (TheRow > 0) then // выбор первой колонки
      begin
       WhichKey := 0;
     if (ssCtrl in Shift) and not ((ssAlt in Shift) or (ssShift in Shift)) then // кнопка Ctrl нажата
          WhichKey := 1;
     if not((ssCtrl in Shift) or (ssAlt in Shift)) and (ssShift in Shift) then // кнопка Shift нажата 
        begin
          Linestring.Add(IntToStr(TheRow)); сохранение выбранных элементов в последовательности
          WhichKey := 2;
        end;
      end;

      SelectRow(WhichKey,TheRow); //определение выбранного элемента в зависимости от нажатых клавиш и строки
    end;
  end;
end;

procedure TForm1.SelectRow(var TheKey, ThisRow : Integer);
var
 I, J, MaxRow, MinRow, CurrentRow, LastRow : Integer;
begin
 case TheKey of
  0 : begin
       GStringL.Clear;
       Linestring.Clear;
       GStringL.Add(GenStringGrid.Rows[ThisRow].Strings[0]);
      end;
  1 : begin
       I := GStringL.IndexOf(GenStringGrid.Rows[ThisRow].Strings[0]);
       if I < 0 then
          GStringL.Add(GenStringGrid.Rows[ThisRow].Strings[0]);
      end;
  2 : begin
       I := Linestring.Count;
       if I > 0 then
         LastRow := StrToInt(Linestring.Strings[0])
       else
         LastRow := 1;
       CurrentRow := ThisRow;
       if LastRow < CurrentRow then
        begin
         MinRow := LastRow;
         MaxRow := CurrentRow;
        end
       else
        begin
         MinRow := CurrentRow;
         MaxRow := LastRow;
        end;
       for J := MinRow to MaxRow do
        begin
         I := GStringL.IndexOf(GenStringGrid.Rows[J].Strings[0]);
         if I < 0 then
          begin
            GStringL.Add(GenStringGrid.Rows[J].Strings[0]);
          end;
        end;
      end;
 end;
 PaintGrid;  // перерисовка выбранных ячеек
end;

Следующая процедура перерисовывает выбранные ячейки :
procedure TForm1.PaintGrid;
var
 I, J : Integer;
 TheRow, TheCol : LongInt;
 RectCell : TRect;
 GString : String;
begin
 TheCol := 0;
 for I := GenStringGrid.TopRow to (GenStringGrid.TopRow + GenStringGrid.VisibleRowCount - 1) do
  begin
   J := GStringL.IndexOf(GenStringGrid.Rows[I].Strings[0]);
   TheRow := StrToInt(GenStringGrid.Rows[I].Strings[0]);
   RectCell := GenStringGrid.CellRect(TheCol,TheRow);
   GenStringGrid.Canvas.FillRect(RectCell);
   GString := GenStringGrid.Cells[TheCol,TheRow];

   if J < 0 then
    begin
     GenStringGrid.Canvas.Font.Color := GenStringGrid.Font.Color;
     GenStringGrid.Canvas.Brush.Color := GenStringGrid.Color;
    end
   else
    begin
     GenStringGrid.Canvas.Font.Color := clWhite;
     GenStringGrid.Canvas.Brush.Color := clRed;
    end;
   GenStringGrid.Canvas.FillRect(RectCell);
   DrawText(GenStringGrid.Canvas.Handle,PChar(GString),StrLen(PChar(GString)),RectCell,DT_Left);
  end;
end;

Возврат в Tips&Tricks