2012-04-12 22 views
7

मैं नियंत्रण की दृश्यता को नियंत्रित करने के लिए एक क्रिया का उपयोग करने की कोशिश कर रहा हूं। मेरे कोड इस तरह दिखता है:नियंत्रण की दृश्यता निर्धारित करने के लिए मैं एक क्रिया का उपयोग कैसे कर सकता हूं?

पास्कल फ़ाइल

unit Unit1; 

interface 

uses 
    Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ActnList, StdCtrls; 

type 
    TForm1 = class(TForm) 
    Button1: TButton; 
    ActionList1: TActionList; 
    Action1: TAction; 
    CheckBox1: TCheckBox; 
    procedure Action1Update(Sender: TObject); 
    end; 

var 
    Form1: TForm1; 

implementation 

{$R *.dfm} 

procedure TForm1.Action1Update(Sender: TObject); 
begin 
    (Sender as TAction).Visible := CheckBox1.Checked; 
end; 

end. 

फार्म फ़ाइल

object Form1: TForm1 
    object Button1: TButton 
    Left = 8 
    Top = 31 
    Action = Action1 
    end 
    object CheckBox1: TCheckBox 
    Left = 8 
    Top = 8 
    Caption = 'CheckBox1' 
    Checked = True 
    State = cbChecked 
    end 
    object ActionList1: TActionList 
    Left = 128 
    Top = 8 
    object Action1: TAction 
     Caption = 'Action1' 
     OnUpdate = Action1Update 
    end 
    end 
end 

प्रपत्र पहले चलाता बटन दिखाई देता है और चेक बॉक्स को चेक किया गया है। फिर मैं चेक बॉक्स को अन-चेक करता हूं और बटन गायब हो जाता है। जब मैं चेक बॉक्स को दोबारा जांचता हूं तो बटन फिर से दिखने में विफल रहता है।

मुझे लगता है कि इस का कारण यह TCustomForm.UpdateActions में निम्नलिखित स्थानीय समारोह के अंदर पाया जा सकता है:

procedure TraverseClients(Container: TWinControl); 
var 
    I: Integer; 
    Control: TControl; 
begin 
    if Container.Showing and not (csDesigning in Container.ComponentState) then 
    for I := 0 to Container.ControlCount - 1 do 
    begin 
     Control := Container.Controls[I]; 
     if (csActionClient in Control.ControlStyle) and Control.Visible then 
      Control.InitiateAction; 
     if (Control is TWinControl) and (TWinControl(Control).ControlCount > 0) then 
     TraverseClients(TWinControl(Control)); 
    end; 
end; 

Control.Visible की जांच कभी खुद को फिर से अद्यतन करने के लिए एक मौका हो रही मेरी कार्रवाई को रोकने के लिए प्रकट होता है।

क्या मैंने इस मुद्दे का सही ढंग से निदान किया है? क्या यह डिज़ाइन द्वारा है या क्या मुझे क्यूसी रिपोर्ट जमा करनी चाहिए? क्या किसी को कामकाज के बारे में पता है?

+0

उहम, आप ['OnUpdate'] (http://docwiki.embarcadero.com/Libraries/en/Vcl.ActnList.TAction.OnUpdate) का उपयोग क्यों कर रहे हैं? – TLama

+0

@TLama: क्योंकि यही वह है। अक्सर, मुझे लगता है कि, आप 'दृश्यमान' की बजाय 'सक्षम 'सेट करते हैं। –

+0

यह एक बग है, या कम से कम एक Misbegotten- फ़ीचर। आप किसी भी कार्रवाई पर सक्षम और दृश्यमान सेट करने में सक्षम होना चाहिए, और किसी भी लिंक किए गए नियंत्रण को सक्षम किए गए मान और दृश्यमान के उस मूल्य को रीफ्रेश किया जाना चाहिए। यदि यहां एक्शन अपडेट की आवश्यकता है, तो यह उस प्रकार की डिकूप्लिंग को तोड़ देता है जिसे आप करने का प्रयास कर रहे हैं। चेकबॉक्स को अब कार्रवाई के साथ जोड़ा जाना है। मैं केवल दृश्य में किसी भी बदलाव के लिए ऑनअपडेट का उपयोग करना बंद कर दूंगा, और चेकबॉक्स ऑनक्लिक में केवल एक पंक्ति के रूप में दिखाई देने वाली या दृश्य दिखाई नहीं दे सकता। –

उत्तर

8

आपका निदान सही है। कार्रवाइयों ने इस तरह से काम किया है क्योंकि उन्हें पहली बार डेल्फी से पेश किया गया था।

मुझे उम्मीद है कि यह डिज़ाइन (पाठ के अत्यधिक अद्यतन से बचने और अदृश्य नियंत्रण के अन्य दृश्य पहलुओं से बचने के लिए अनुकूलन) है, लेकिन इसका मतलब यह नहीं है कि डिज़ाइन अच्छा है।

कोई भी कामकाज जिसे मैं कल्पना कर सकता हूं, इसमें आपके चेकबॉक्स कोड को सीधे प्रभावित क्रियाओं में हेरफेर करना शामिल होगा, जो बहुत ही सुरुचिपूर्ण नहीं है क्योंकि इसे प्रभावित होने वाली हर चीज़ के बारे में जागरूक नहीं होना चाहिए - यही OnUpdate घटना है आपके लिए करता हूं। जब चेकबॉक्स चेक हो जाता है, तो Action1.Update पर कॉल करें, या यदि यह काम नहीं करता है, तो Action1.Visible := True

आप इसके बजाय TActionList.OnUpdate ईवेंट में अपना एक्शन-अपडेटिंग कोड भी डाल सकते हैं।

+1

धन्यवाद। मुझे आश्चर्य है कि मैंने पहले यह नहीं देखा है लेकिन मुझे आश्वस्त किया गया है कि आप इस मुद्दे के बारे में पहले ही जानते थे। मेरे पास पहले से ही मेरे सामान्य बेस क्लास फॉर्म में 'TCustomForm.UpdateActions' का ओवरराइड है। तो मैं जिस तरह से अद्यतन करना चाहता हूं, उसे अपडेट करने के लिए मैं वहां काम कर सकता हूं। यह शायद मेरे लिए सबसे आसान मार्ग है। –

2

संबंधित नियंत्रण दिखाई नहीं देते हैं जब ActionUpdate ईवेंट नहीं कहा जाता है। चेकबॉक्स 1 के क्लिक ईवेंट पर एक्शनअपडेट कॉल करने की कोशिश करें।

+0

हैं जो "क्रियाओं का उपयोग करना बंद करें" कहने जैसा है। –

+0

कोई डेविड नहीं। क्रियाएं अच्छी हैं। लेकिन रॉब ने कहा, उनके डिजाइन में आपके डिजाइन बुरा है। –

+0

लेकिन समस्या का सबसे अच्छा समाधान मेरे जीयूआई नियंत्रण को एक साथ जोड़ नहीं सकता है। उस नरक से बचने का कारण है कि मैंने पहली जगह में क्रियाओं का उपयोग करना शुरू कर दिया। –

4

हाँ आपका निदान सही है क्योंकि रॉब ने पहले ही कहा और समझाया। चारों ओर एक कार्य व्यक्तिगत TAction के OnUpdate ईवेंट हैंडलर का उपयोग नहीं करना है, लेकिन TActionList के ऑन अपडेट ईवेंट ईवेंट हैंडलर का उपयोग करना है।

procedure TForm1.ActionList1Update(Action: TBasicAction; var Handled: Boolean); 
begin 
    Handled := True; 
    Action1.Visible := CheckBox1.Checked; 
end; 

आप इस के लिए किसी लिंक किए गए कार्रवाई काम करने के लिए के साथ कम से कम एक दिखाई नियंत्रण, अन्यथा ActionList के OnUpdate हैंडलर या तो नहीं कहा जा जाएगा की जरूरत है।

बीटीडब्ल्यू, जब क्रियाएं और कार्यसूची पहली बार पेश की गईं, रे कोनोपा (राइज घटकों) ने उनके कार्यान्वयन पर कुछ लेख लिखे और उन्हें उपयोग करने के तरीके पर बहुत अच्छी सलाह दी। तब से, मैंने प्रत्येक व्यक्तिगत कार्रवाई के ऑनएक्सक्यूट का उपयोग करने के अभ्यास को अपनाया है, लेकिन एक्शनलिस्ट के ऑन अपडेट का उपयोग करने के लिए। साथ ही, मैं उस हैंडलर में पहली चीज को हैंडल टू ट्रू सेट करना है, इसलिए इसे जरूरी से अधिक नहीं कहा जाएगा, और उस हैंडलर में केवल एक बार एक्शन की सक्षम संपत्ति को बदलने के लिए, इसलिए परिणामस्वरूप जीयूआई झिलमिलाहट नहीं करेगा इसे बंद करने और फिर चालू करने के लिए।

रे कोनोपा द्वारा अनुच्छेद "प्रभावी रूप से कार्य सूची का उपयोग कर रहा है": http://edn.embarcadero.com/article/27058 रे के पास अपनी साइट पर तीन लेख होते थे, लेकिन एम्बरकेडरो पर एक होता है, लेकिन यह "संयुक्त" संस्करण भी हो सकता है (ऐसा नहीं है मूल काम आसान है)।

+2

इसके लिए धन्यवाद। मैं रे के लेख देख लूंगा। मैं सूची के लिए 'ऑनअपडेट' के बारे में कभी भी अवगत नहीं था लेकिन कल्पना कर सकता हूं कि इसका परिणाम कोड का एक अच्छा केंद्रीकरण होगा। –

+1

@ डेविड हेफरन: हाँ, कोड केंद्रीकरण इसलिए मैं इसका उपयोग करता हूं। –

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

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