StringGridで複数行選択はどうするのでしょうか?
Options のgoRowSelectでは、一行だけだし、
goRangeSelect では、範囲選択になってしまいます。
[Shift]キーや[Ctrl]キーで、行飛ばしも可能な選択にしたいのです。
このように書くと、ListViewで実装しなさいと言われそうですが、
当初ListViewで問題なかったのですが、固定カラムの要望がでまして、
(スクロールしても、最初の2列はスクロールしない等)
ListViewでは、固定カラムはできないですよね?
そこで、StringGridに変更した訳です。
ですが、複数行選択できないなんて知りませんでした。
これでは、StringGridに変更した意味が。。。
一番いいのは、ListViewでの固定カラムが実現できれば問題ないのですが。
↑は愚痴ですので。。。(^^;
StringGridで複数行選択の方法を教えてください。
よろしくお願いします。
連続した複数行は [SHIFT] を押しながらで選択する事が出来ますが
行飛ばしの複数行選択(複数のRect)を選択する事は出来ません
procedure TCustomGrid.Paint; を見てもらうと分かりますが
Selection : TGridRect に設定されているエリアを gdSelected を見なしているからです。
[CTRL] で StringGrid1.Selection を累積していきそれを
StringGrid1DrawCellで描画に反映させれば良いわけで
こんな感じで CTRL で 複数エリア指定する事が可能になります
SelectionRects : TList;
implementation
{$R *.dfm}
//Grids.pas からコピー
function PointInGridRect(Col, Row: Longint; const Rect: TGridRect): Boolean;
begin
Result := (Col >= Rect.Left) and (Col <= Rect.Right) and (Row >= Rect.Top)
and (Row <= Rect.Bottom);
end;
procedure TForm2.SelectionClear;
var
I : Integer;
begin
for I:=0 to SelectionRects.Count -1 do
begin
Dispose(SelectionRects[I]);
end;
SelectionRects.Clear;
end;
procedure TForm2.FormCreate(Sender: TObject);
begin
SelectionRects := TList.Create;
end;
procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
begin
SelectionClear;
SelectionRects.Free;
end;
procedure TForm2.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
Rect: TRect; State: TGridDrawState);
var
ARect : ^TGridRect;
I : Integer;
begin
if gdSelected in State then
begin
StringGrid1.Canvas.Brush.Color := clRed;
StringGrid1.Canvas.FillRect(Rect);
end;
for I:=0 to SelectionRects.Count-1 do
begin
ARect := SelectionRects[I];
if PointInGridRect(ACol,ARow,ARect^) = True then
begin
StringGrid1.Canvas.Brush.Color := clRed;
StringGrid1.Canvas.FillRect(Rect);
end;
end;
end;
procedure TForm2.StringGrid1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if (not (ssCTRL in SHIFT)) and (not (ssSHIFT in SHIFT)) then
begin
SelectionClear;
StringGrid1.Invalidate;
end;
end;
procedure TForm2.StringGrid1MouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
var
ARect : ^TGridRect;
begin
if (ssCTRL in SHIFT) or (ssSHIFT in SHIFT) then
begin
New(ARect);
ARect^ := StringGrid1.Selection;
SelectionRects.Add(ARect);
StringGrid1.Invalidate;
end
else
begin
SelectionClear;
New(ARect);
ARect^ := StringGrid1.Selection;
SelectionRects.Add(ARect);
StringGrid1.Invalidate;
end;
end;
KHE00221様、レス有難うございます。
やはり標準機能では無理ですか。。
[Ctrl],[Shift]キー処理をして、自前の選択行リストなるものを用意して
標準描画しない(DefaultDrwaing=False) で地道に描画させるしか
方法は無いのですね?
KHE00221様、レス有難うございます。
返信書いてる間に、新たなレスが。。。
しかもサンプルまで載せて頂いて有難うございます。
早速、参考にさせていただきます。
KHE00221様、完璧です。
Selection(TGridRect)を生かしながら実装できるのですね。
私が考えていたのは、行のみ保持する方法だったのですが、
とても勉強になります。
あとは、同じ行でクリックされた場合の選択反転を実装すれば
希望どうりの動作になります。
迅速なレスに感謝です。
本当に有難うございました。
ツイート | ![]() |