2015-10-14 3 views
1

Я пытаюсь написать индивидуальный выбор даты (календарь). Даты будут отображаться на stringgrid. Я пытаюсь заполнить выбранную ячейку специальным цветом и сделать выделенным celltext жирным.Как заполнить ячейку сетки строк пользовательским цветом?

Вот мой код:

type 
     TStringGrid = Class(Vcl.Grids.TStringGrid) 
     private 
     FHideFocusRect: Boolean; 
     protected 
     Procedure Paint;override; 
     public 
     Property HideFocusRect:Boolean Read FHideFocusRect Write FHideFocusRect; 
     End; 


    TfrmNepaliCalendar = class(TForm) 
    ... 
    ... 
    ... 
    end; 


    procedure TfrmNepaliCalendar.StringGridDrawCell(Sender: TObject; ACol, ARow: Integer; 
     Rect: TRect; State: TGridDrawState); 
    begin 
     if gdSelected in State then begin 
     StringGrid.Canvas.Brush.Color := $00940A4B; 
     StringGrid.Canvas.FillRect(Rect); 

     StringGrid.Canvas.Font.Style := [fsBold]; 
     StringGrid.Canvas.Font.Color := clHighlightText; 
     StringGrid.Canvas.TextOut(Rect.Left + 3, Rect.Top + 5, StringGrid.Cells[ACol,ARow]); 

     StringGrid.HideFocusRect := True; 
     end; 
    end; 


{ TStringGrid } 

procedure TStringGrid.Paint; 
var 
    LRect: TRect; 
begin 
    inherited; 
    if HideFocusRect then begin 
    LRect := CellRect(Col,Row); 
    if DrawingStyle = gdsThemed then InflateRect(LRect,-1,-1); 

    DrawFocusrect(Canvas.Handle,LRect) 
    end; 
end; 

выход, я получаю:

When clicked on cell containing no text

When clicked, the background is clipped from left

Проблема № 1: Мне нужно, чтобы скрыть, что нежелательный прямоугольник появляться как граница для выбранной ячейки

Проблема № 2: Избегайте фон ячейки вырезку

ответ

3

В процедуре OnDrawCell добавить непосредственно перед FillRect

Rect.Left := Rect.Left-4; 

Кажется, работает.


Альтернативного

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

Но вот альтернатива, которая решает обе проблемы. Это требует немного больше кодирования, но не так много. С другой стороны, подклассов TStringGrid не нужен, ни Rect регулировка

Основой является отключение чертежа по умолчанию, поэтому установить свойство сеток DefaultDrawing := false; , а затем добавить к событию OnDrawCell:

procedure TForm1.StringGridDrawCell(Sender: TObject; ACol, ARow: Integer; 
    Rect: TRect; State: TGridDrawState); 
begin 
    if gdFixed in State then 
    begin 
    StringGrid.Canvas.Brush.Color := clGradientInactiveCaption; 
    StringGrid.Canvas.Font.Style := []; 
    StringGrid.Canvas.Font.Color := clBlack; 
    end 
    else 
    if gdSelected in State then 
    begin 
    StringGrid.Canvas.Brush.Color := $00940A4B; 
    StringGrid.Canvas.Font.Style := [fsBold]; 
    StringGrid.Canvas.Font.Color := clHighlightText; 
    end 
    else 
    begin 
    StringGrid.Canvas.Brush.Color := $00FFFFFF; 
    StringGrid.Canvas.Font.Style := []; 
    StringGrid.Canvas.Font.Color := clWindowText; 
    end; 

    StringGrid.Canvas.FillRect(Rect); 
    StringGrid.Canvas.TextOut(Rect.Left + 3, Rect.Top + 5, StringGrid.Cells[ACol,ARow]); 
end; 

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

Sample grid

+0

Я удалил свой ответ по вашему предложению. Однако, я полагаю, вы можете использовать предложение из своей части в своем ответе. 'StringGrid.Canvas.FillRect (TStringGrid (Sender) .CellRect (ACol, ARow));' кажется более естественным, чем 'Rect.Left: = Rect.Left-4;'. Это может помочь ОП. –

+0

@ asd-tm О, это не было мое предложение удалить ваш ответ. Без стандартного рисования -4 больше не требуется! Вызов функции CellRect(), чтобы изменить свойство 'Left', похоже на чрезмерное использование в методе« Paint ». Если вы посмотрите в исходном коде, вы увидите, что 'ARect.Left' будет увеличен с буквальным« 4 ». Не могу сказать номер строки, я больше не открываю его. –

+0

О, нет, Том, я тебя не обвиняю. Более того, я благодарю вас за ваше предложение. Теперь я получил ваше мнение о «4» буквальном и подтвердил ваш ответ. –

2

Я предполагаю, что вы (хотите) использовать настройки по умолчанию DefaultDrawing = True, в противном случае ваш вопрос не существует.

  1. Чтобы избавиться от фокуса прямоугольника, что вам нужно сделать это еще раз (потому что это XOR-операция, фокус Прямоугольник исчезнет), или предотвратить его втягивание.

    Чертеж снова делается путем использования OnDrawCell событие:

    procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer; 
        Rect: TRect; State: TGridDrawState); 
    begin 
        if gdFocused in State then 
        DrawFocusRect(StringGrid1.Canvas.Handle, Rect); 
    end; 
    

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

    type 
        TStringGrid = class(Vcl.Grids.TStringGrid) 
        public 
        function CanFocus: Boolean; override; 
        end; 
    
    function TStringGrid.CanFocus: Boolean; 
    begin 
        Result := False; 
    end; 
    

    На самом деле это немного странно, рабочее решение, потому что вы все еще в состоянии вкладки в элемент управления, и он держит в ответ на события клавиатуры.

  2. Я не могу воспроизвести вашу cliping проблемы с этим кодом (XE2 здесь):

    procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer; 
        Rect: TRect; State: TGridDrawState); 
    begin 
        if gdSelected in State then 
        begin 
        StringGrid1.Canvas.Brush.Color := $00940A4B; 
        StringGrid1.Canvas.FillRect(Rect); 
        StringGrid1.Canvas.Font.Style := [fsBold]; 
        StringGrid1.Canvas.Font.Color := clHighlightText; 
        StringGrid1.Canvas.TextOut(Rect.Left + 3, Rect.Top + 5, 
         StringGrid1.Cells[ACol, ARow]); 
        end; 
    end; 
    

    Rect будет и правильного CellRect. Эффект скрепки связан с чем-то другим в другом месте.

    Но если действительно есть поддельная +4 в исходном коде X Е8, как Tom Brunberg mentions, который легко преодолеть с -4, то, что, очевидно, является ошибкой и должно быть сообщено.

+0

Что касается обрезки, я использую XE7, но я вижу точно такое же обрезание, как и Раби. В Vcl.Grids, TStringGrid.DrawCell(), 'if DefaultDrawing затем начнется, если StyleServices.Enabled затем начнет ARect.Left: = ARect.Left + 4;'. Затем ARect передается на «унаследованный DrawCell()», который вызывает «FOnDrawCell()». Я не установил XE8, не могли бы вы подтвердить, что XE8 так же изменяет «ARect.Left»? –

+1

Что касается фокуса rect, +1 для 'DrawFocusRect()' в 'OnDrawCell' и, упоминая, что это функция XOR, я этого не знал. Он работает, но Rect (исправленный -4) должен быть завышен -1, -1, чтобы соответствовать внутреннему чертежу сетки, и он должен быть в конце OnDrawCell в случае, если Rect заполняется раньше. –

+0

@Tom Aha, 'StyleServices.Enabled', теперь я вижу! Действительно, XE2 имеет ту же ошибку. – NGLN

Смежные вопросы