Tôi đã tạo một thành phần, TGridPaintBox, dựa trên TPaintBox. Về cơ bản nó là một hộp sơn có thêm "chức năng lưới". Nó không phải là một lưới dữ liệu. Giống như một thành phần của bàn cờ.Tại sao bản cập nhật thành phần tùy chỉnh của tôi không thay đổi khi tôi thay đổi các thuộc tính?
Trong trình khám phá đối tượng, tôi có thể đặt các thuộc tính nhất định. Quan trọng nhất là tôi có thể thiết lập kích thước lưới (bao nhiêu ô trên/xuống), nhưng cũng có các tùy chọn liên quan đến bản vẽ. Cho dù các ô phải là hình vuông, màu của các ô lẻ/chẵn, vv
Phiên bản đầu tiên của thành phần này có thuộc tính trực tiếp trên lớp và khi tôi thay đổi thuộc tính, bản vẽ designtime được cập nhật ngay lập tức. Khi thành phần phát triển, tôi muốn tổ chức các thuộc tính của mình tốt hơn một chút và giới thiệu một số "thuộc tính tùy chọn", như các tùy chọn vẽ, tùy chọn hành vi, v.v. Sau khi giới thiệu, bản vẽ designtime không còn cập nhật như trước nữa. Sau khi thay đổi thuộc tính, tôi phải bấm vào thành phần để nó cập nhật. Bất cứ ai có thể cho tôi biết lý do tại sao điều này xảy ra?
Đây là phiên bản rút gọn của mã. Tôi hy vọng nó sẽ giải thích hành vi:
(PS: Đây là thành phần đầu tiên của tôi, mặc dù tôi đã sử dụng Delphi từ năm 1997, vì vậy nếu ai đó có thể phát hiện bất cứ điều gì ngu ngốc theo cách tôi đã làm miễn phí cho tôi biết)
unit GridPaintBox;
interface
type
TGridDrawOption = (gdoSquareCells,gdoCenterCells,gdoDrawCellEdges,gdoDrawFocus);
TGridDrawOptions = set of TGridDrawOption;
TGridOptions = class(TPersistent)
private
FCellsX : integer;
FCellsY : integer;
FDrawOptions : TGridDrawOptions;
public
constructor Create(aGridPaintBox : TGridPaintBox);
procedure Assign(Source : TPersistent); override;
published
property CellsX : integer read FCellsX write FCellsX;
property CellsY : integer read FCellsY write FCellsY;
property DrawOptions : TGridDrawOptions read FDrawOptions write FDrawOptions;
end;
TGridPaintBox = class(TPaintBox)
private
FGridOptions : TGridOptions;
FFocusedX,
FFocusedY : integer;
FOnFocusChanged: TNotifyEvent;
procedure CalculateSizeAndPosition;
procedure DrawCell(X,Y : integer);
procedure DrawCells;
procedure SetGridOptions(const Value: TGridOptions);
protected
procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
public
constructor Create(aOwner : TComponent); override;
destructor Destroy; override;
procedure Paint; override;
procedure SetFocus(X,Y : integer);
published
property OnFocusChanged : TNotifyEvent read FOnFocusChanged write FOnFocusChanged;
property Options : TGridOptions read FGridOptions write SetGridOptions;
end;
procedure Register;
implementation
procedure Register;
begin
RegisterComponents('Samples', [TGridPaintBox]);
end;
procedure TGridPaintBox.CalculateSizeAndPosition;
begin
<...>
end;
constructor TGridPaintBox.Create(aOwner: TComponent);
begin
inherited;
FGridOptions := TGridOptions.Create(self);
end;
procedure TGridPaintBox.DrawCell(X, Y: integer);
begin
<...>
end;
procedure TGridPaintBox.DrawCells;
var
X,Y : integer;
begin
CalculateSizeAndPosition;
for Y := 0 to FGridOptions.CellsY-1 do
for X := 0 to FGridOptions.CellsX-1 do
DrawCell(X,Y);
end;
procedure TGridPaintBox.Paint;
begin
Canvas.Font := Font;
Canvas.Brush.Color := Color;
Canvas.Brush.Style := bsSolid;
Canvas.FillRect(Rect(0,0,Width,Height));
DrawCells;
if Assigned(OnPaint) then
OnPaint(Self);
end;
procedure TGridPaintBox.SetGridOptions(const Value: TGridOptions);
begin
FGridOptions.Assign(Value);
invalidate;
end;
procedure TGridPaintBox.MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
SetFocus(PixelToCellX(X),PixelToCellY(Y));
inherited;
end;
procedure TGridPaintBox.SetFocus(X, Y: integer);
begin
if (FocusedX=X) and (FocusedY=Y) then
exit;
FFocusedX := X;
FFocusedY := Y;
if assigned(OnFocusChanged) then
OnFocusChanged(self);
invalidate;
end;
constructor TGridOptions.Create(aGridPaintBox : TGridPaintBox);
begin
FCellsX := 20;
FCellsY := 8;
FDrawOptions := [gdoSquareCells,gdoCenterCells,gdoDrawCellEdges];
end;
procedure TGridOptions.Assign(Source : TPersistent);
begin
if Source is TGridOptions then
begin
FCellsX := TGridOptions(Source).CellsX;
FCellsY := TGridOptions(Source).CellsY;
FDrawOptions := TGridOptions(Source).DrawOptions;
end
else
inherited;
end;
end.
Vâng, lỗi chính tả. Đó là thực sự trong lớp TGridPaintBox, nhưng tôi sai lầm khi chỉnh sửa cho bài đăng này. Tôi sẽ cập nhật câu hỏi của mình. –
Ngoài ra, cảm ơn cho tip về bắt nguồn từ TGraphicControl hơn là TPaintBox. Và tất nhiên, cảm ơn phần còn lại của câu trả lời. Nó giải quyết vấn đề của tôi :-) –