2008. január 29., kedd
Force a selection of cells in a TStringGrid
Problem/Question/Abstract:
I'm attempting to force a selection of cells based on the user clicking in the grid. Here is my code:
procedure TSizeSelectFrm.SizeSelectStrngGrdSelectCell(Sender: TObject;
ACol, ARow: Integer; var CanSelect: Boolean);
var
Select: TGridRect;
begin
CanSelect := False;
Select.Left := 0;
Select.Right := 2;
if ARow < 10 then
begin
Select.Top := ARow;
Select.Bottom := SizeSelectStrngGrd.Selection.Bottom;
end;
if ARow > 10 then
begin
Select.Top := SizeSelectStrngGrd.Selection.Top;
Select.Bottom := ARow;
end;
SizeSelectStrngGrd.Selection := Select;
end;
What happens is sometimes the selected cells don't always select properly. In the debugger, the value for select seems to be always set properly. Is there something wrong with the way I'm "applying" the selection?
Answer:
Your selection is overwritten when the mouse crosses a cell boundary or when the mouse button is released. SizeSelectStrngGrd.Selection. Right is made to correspond to the most recent cursor position. You can put it back like so:
procedure TForm1.SizeSelectStrngGrdMouseUp(Sender: TObject;
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
Select: TGridRect;
begin
{When the mouse button is released set the right of the selected range}
Select := SizeSelectStrngGrd.Selection;
Select.Right := 2;
SizeSelectStrngGrd.Selection := Select;
{Record that the mouse button is up}
MouseDown := false;
end;
MouseDown is a class-scope Boolean that is used later. The mouse up handler above gives the right selection, but the grid looks naff as the selected area spreads out to the right then contracts when the mouse button is released. You can improve on that by recording whether the left mouse button is up or down:
procedure TForm1.SizeSelectStrngGrdMouseDown(Sender: TObject;
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
{Record that the mouse button is down}
MouseDown := mbLeft = Button;
end;
and controlling how the grid is drawn so that cells you don't want to be selected are not drawn as though they were selected:
procedure TForm1.SizeSelectStrngGrdDrawCell(Sender: TObject;
ACol, ARow: Integer; Rect: TRect; State: TGridDrawState);
begin
{When the mouse is down only allow cells in column two to be drawn as though they are selected}
if ((ACol <> 2) and (gdSelected in State) and MouseDown) then
State := State - [gdSelected];
with SizeSelectStrngGrd.Canvas do
begin
{Choose a brush colour to suit the cell}
if gdFixed in State then
Brush.Color := clBtnFace
else if gdSelected in State then
Brush.Color := clHighlight
else
Brush.Color := clWindow;
{Colour the cell background}
FillRect(Rect);
{Display the text}
TextOut(Rect.Left + 2, Rect.Top + 2, SizeSelectStrngGrd.Cells[ACol, ARow]);
end;
end;
This will likely need some polishing before it's ready for use, but it does let you control what is
selected.
Feliratkozás:
Megjegyzések küldése (Atom)
Nincsenek megjegyzések:
Megjegyzés küldése