2012-06-10 16 views
12

मैंने TPaintBox पर आधारित एक घटक, TGridPaintBox बनाया है। यह मूल रूप से "ग्रिड कार्यक्षमता" के साथ एक पेंटबॉक्स है। यह डेटा ग्रिड नहीं है। एक शतरंज बोर्ड घटक की तरह अधिक।जब मैं गुण बदलता हूं तो मेरा कस्टम घटक अपडेट क्यों नहीं होता है?

ऑब्जेक्ट एक्सप्लोरर में मैं कुछ गुण सेट कर सकता हूं। सबसे महत्वपूर्ण बात यह है कि मैं ग्रिड आयाम (कितनी कोशिकाओं को नीचे/नीचे) सेट कर सकता हूं, लेकिन ड्राइंग से संबंधित विकल्प भी सेट कर सकता हूं। चाहे कोशिकाएं वर्ग हों, अजीब/यहां तक ​​कि कोशिकाओं आदि का रंग

इस घटक का मेरा पहला संस्करण सीधे वर्ग पर गुण था, और जब मैंने एक संपत्ति बदल दी, तो डिजाइनटाइम ड्राइंग तुरंत अपडेट किया गया था। जैसे-जैसे घटक बढ़ता गया, मैं अपनी संपत्तियों को थोड़ा बेहतर व्यवस्थित करना चाहता था, और ड्राइंग विकल्पों, व्यवहार विकल्पों आदि जैसे कुछ "विकल्प गुण" पेश किए। इसे शुरू करने के बाद, डिज़ाइनटाइम ड्राइंग अब पहले की तरह अपडेट नहीं होता है। एक संपत्ति बदलने के बाद, मुझे इसे अद्यतन करने के लिए घटक पर क्लिक करना होगा। क्या कोई मुझे बता सकता है कि ऐसा क्यों होता है?

यहां कोड का एक अलग संस्करण है। मुझे उम्मीद है कि यह व्यवहार की व्याख्या करेगा:

(पीएस: यह मेरा पहला घटक है, भले ही मैं 1 99 7 से डेल्फी का उपयोग कर रहा हूं, इसलिए यदि कोई भी इसे करने के तरीके में बेवकूफ़ बना सकता है, तो कृपया महसूस करें मुझे) बताने के लिए

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. 

उत्तर

13

यह होता है क्योंकि आप विकल्प सेट जो आपके नियंत्रण के अंतर्गत आता है जो अमान्य होगा के लिए एक सेटर की जरूरत नहीं है मुफ्त। फॉर्म डिज़ाइनर में क्लिक हालांकि नियंत्रण को अमान्य करने के लिए आमंत्रित करता है, लेकिन आपको इसे अपने विकल्प सेटर में स्वयं ही संभालना चाहिए। इसलिए मैं सीधा मालिक वर्ग उदाहरण के लिए और में विकल्प इस मालिक मजबूर सेटर बेहतर उपयोग के लिए विकल्प मालिक संग्रहीत करेंगे, नियंत्रण पुनः बनाने का:

type 
    TGridPaintBox = class; 
    TGridDrawOption = (gdoSquareCells, gdoCenterCells, gdoDrawCellEdges, gdoDrawFocus); 
    TGridDrawOptions = set of TGridDrawOption; 
    TGridOptions = class(TPersistent) 
    private 
    FOwner: TGridPaintBox; 
    FCellsX: Integer; 
    FCellsY: Integer; 
    FDrawOptions: TGridDrawOptions; 
    procedure SetCellsX(AValue: Integer); 
    procedure SetCellsY(AValue: Integer); 
    procedure SetDrawOptions(const AValue: TGridDrawOptions); 
    public 
    constructor Create(AOwner: TGridPaintBox); 
    procedure Assign(ASource: TPersistent); override; 
    published 
    property CellsX: Integer read FCellsX write SetCellsX; 
    property CellsY: Integer read FCellsY write SetCellsY; 
    property DrawOptions: TGridDrawOptions read FDrawOptions write SetDrawOptions; 
    end; 

implementation 

constructor TGridOptions.Create(AOwner: TGridPaintBox); 
begin 
    FOwner := AOwner; 
    FCellsX := 20; 
    FCellsY := 8; 
    FDrawOptions := [gdoSquareCells, gdoCenterCells, gdoDrawCellEdges]; 
end; 

procedure TGridOptions.SetCellsX(AValue: Integer); 
begin 
    if FCellsX <> AValue then 
    begin 
    FCellsX := AValue; 
    FOwner.Invalidate; 
    end; 
end; 

procedure TGridOptions.SetCellsY(AValue: Integer); 
begin 
    if FCellsY <> AValue then 
    begin 
    FCellsY := AValue; 
    FOwner.Invalidate; 
    end; 
end; 

procedure TGridOptions.SetDrawOptions(const AValue: TGridDrawOptions); 
begin 
    if FDrawOptions <> AValue then 
    begin 
    FDrawOptions := AValue; 
    FOwner.Invalidate; 
    end; 
end; 

इसके अलावा नोट:

आप तो स्पष्ट रूप से रंग बॉक्स 'प्रकाशित गुण और उदाहरण Color, Font या OnPaint घटना के लिए तरह की घटनाओं की आवश्यकता नहीं है, TGraphicControl से बजाय TPaintBox से अपने नियंत्रण निकाले जाते हैं। आप चुन सकते हैं कि आप अपनी संपत्तियों और घटनाओं को स्वयं प्रकाशित करेंगे।

+1

हाँ, टाइपो। यह वास्तव में टीजीआईआरपींटबॉक्स वर्ग में है, लेकिन इस पोस्ट के लिए संपादन करते समय मैं गड़बड़ कर रहा हूं। मैं अपना प्रश्न अपडेट करूंगा। –

+1

इसके अलावा, TPaintBox के बजाय TGraphicControl से प्राप्त करने के बारे में युक्ति के लिए धन्यवाद। और निश्चित रूप से, बाकी उत्तर के लिए धन्यवाद। यह मेरी समस्या हल :-) –

संबंधित मुद्दे

 संबंधित मुद्दे