Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi 网格网格单元_Delphi_Colors_Click_Cells_Stringgrid - Fatal编程技术网

Delphi 网格网格单元

Delphi 网格网格单元,delphi,colors,click,cells,stringgrid,Delphi,Colors,Click,Cells,Stringgrid,我已经编写了一些代码,根据数据列表,在我的delphi应用程序中为stringgrid上的各个单元格着色 现在,我需要在stringgrid上的OnDblClick事件中编写一些代码,该事件推断单元格是否着色,然后根据找到的结果继续。例如: DOUBLE CLICK CELL IS CELL COLOURED YES > PROCEED A NO > PROCEED B 在将颜色绘制到预定义的TStringGrid.Objects属性时存储颜色。需要检索时,可以

我已经编写了一些代码,根据数据列表,在我的delphi应用程序中为stringgrid上的各个单元格着色

现在,我需要在stringgrid上的
OnDblClick
事件中编写一些代码,该事件推断单元格是否着色,然后根据找到的结果继续。例如:

DOUBLE CLICK CELL  
IS CELL COLOURED  
  YES > PROCEED A  
  NO > PROCEED B

在将颜色绘制到预定义的
TStringGrid.Objects
属性时存储颜色。需要检索时,可以从
坐标中检索。下面是一个简单的示例,根据单元格是否为奇数列,将单元格的
clWhite
clBlack
存储在
Objects
中,并在选中单元格时将存储的值显示为字符串。这应该让你开始

procedure TForm1.FormCreate(Sender: TObject);
var
  r, c: Integer;
const
  ColorSel: array[Boolean] of TColor = (clWhite, clBlack);
begin
  StringGrid1.RowCount := 10;
  StringGrid1.ColCount := 6;
  for c := 1 to StringGrid1.ColCount - 1 do
    for r := 1 to StringGrid1.RowCount - 1 do
    begin
      StringGrid1.Cells[c, r] := Format('C: %d R: %d', [c, r]);
      StringGrid1.Objects[c, r] := TObject(ColorSel[Odd(c)]);
    end;
end;

procedure TForm1.StringGrid1SelectCell(Sender: TObject; ACol, ARow: Integer;
  var CanSelect: Boolean);
begin
  ShowMessage(ColorToString(TColor(StringGrid1.Objects[ACol, ARow])));
end;
您可以在
OnMouseUp
事件中轻松地使用它来检测单元格中的颜色。删除
StringGrid1SelectCell
(使用对象检查器,只需删除事件的值),并将其添加为网格的
OnMouseUp
事件:

procedure TForm1.StringGrid1MouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var
  Col, Row: Integer;
begin
  StringGrid1.MouseToCell(X, Y, Col, Row);
  if (Col > -1) and (Row > -1) then
    ShowMessage(ColorToString(TColor(StringGrid1.Objects[Col, Row])));
end;
处理双击变得非常简单(感谢@TLama的大力协助):


请注意,如果您选择不更改单元格的颜色,您仍应将单元格的默认颜色指定给
对象[列,行]
,以便在那里有一些有意义的内容,以避免在检索值时进行不正确的转换。

您应询问基础数据(您提到的数据列表)根据此条件当前选定的单元格坐标。您是在绘制事件中对单元格进行“着色”还是有底层着色结构?@TLama我可以使用列表中的数据来确定单元格是否已被占用,但这似乎是一个很长的问题@JachGrate我使用
Rect
属性为单元格着色。我刚刚尝试过使用
if-StringGrid.Canvas.Pixels[ACol,ARow]$00FFFFFF-then
它似乎可以工作,但只是在一些时候。我不确定是什么导致它的行为不可预测。不,这是正确的方式!你正在努力解决这个问题。此外,以错误的方式。
Canvas.Pixels
采用像素坐标,而不是网格单元坐标。您必须获取当前选定单元格的单元格矩形,并从该矩形内确定颜色(如果是),但这是错误的。特拉马的原始评论包含了这一见解。最好将应用程序逻辑与演示分离。@TLama:我知道。:-)我想我应该留点东西给OP解决我想我应该顺便提一下
Mouse.CursorPos
,因为
OnDblClick
不包括坐标。也谢谢。:-)@特拉玛:(用我最好的荷马·辛普森的声音)“啊!”你说得对。有一个更简单的解决方案,用你的想法。我只是想得太多了。重新编辑并删除我在此之前的最后几条评论。谢谢。:-)@TLama:修复了OnDblClick处理程序,并为您提供了适当的积分。:-)再次感谢。“我猜是鼠标。光标经过,因为OnDblClick不包含坐标。”这有时会导致相当令人不快的错误,当
鼠标时。光标在点击时返回远离坐标的坐标…@Arioch,在
OnDblClick
事件中,您只需使用
Row
Col
属性即可获得网格坐标,因为双击的第一次单击会选择单元格(当然,如果您没有以某种方式阻止它)。关于鼠标光标位置,
mouse.CursorPos
在内部调用
GetCursorPos
windowsapi函数,因此您将获得新的当前光标位置。
procedure TForm1.StringGrid1DblClick(Sender: TObject);
var
  IsDefaultColor: Boolean;
  CurrCellColor: TColor;
  CurrCol, CurrRow: Integer;
begin
  // Save typing by grabbing the currently selected cell col/row
  CurrCol := StringGrid1.Col;   
  CurrRow := StringGrid1.Row;

  // Get the stored color for the selected cell
  CurrCellColor := TColor(StringGrid1.Objects[CurrCol, CurrRow]);

  // See if it's been painted a different color than the default
  IsDefaultColor := (CurrCellColor = StringGrid1.Color);

  if not IsDefaultColor then
    HandleDifferentColorCell
  else
    HandleNormalColorCell;
end;