2011-04-07 8 views
10

मेरे पास अक्षम किए गए कुछ आइटमों के साथ TComboBox कैसे हो सकता है? मुझे इन वस्तुओं को देखने के लिए उपयोगकर्ता की आवश्यकता है, लेकिन उन्हें चुनने में सक्षम नहीं है।डेल्फी: क्या इसमें अक्षम वस्तुओं के साथ कॉम्बो बॉक्स होना संभव है?

धन्यवाद!

+1

यह प्रश्न के शीर्षक या इसके टैग से स्पष्ट नहीं है पर निम्नलिखित कोड जोड़ने के लिए, लेकिन यहाँ एक घटक विकलांग आइटम समर्थन के साथ TComboBox से व्युत्पन्न के एक कार्यान्वयन है: http: // stackoverflow। कॉम/प्रश्न/4356364 –

+1

ऐसा मत करो। यह उल्लंघन करता है कि उपयोगकर्ता comboboxes से क्या उम्मीद कर रहे हैं। एक और तरीका खोजें। किसी भी मामले में, उपयोगकर्ता को डेटा प्रस्तुत करने के लिए comboboxes एक अच्छा तरीका नहीं है; अगर आपको उनके बारे में एक अवलोकन देखने की आवश्यकता है कि वे क्या कर सकते हैं और नहीं कर सकते हैं, तो उन्हें एक अतिरिक्त कदम नहीं करना चाहिए (यानी ड्रॉप-डाउन बटन दबाएं नहीं)। यह उपयोगकर्ता अनुभव के बारे में सब कुछ है, इसके साथ गड़बड़ मत करो! –

उत्तर

15

हाँ, और यह है कि यह कैसे करना है:

अपने फार्म पर एक TComboBox ड्रॉप, और csOwnerDrawFixed को Style निर्धारित किया है। तब

procedure TForm1.ComboBox1DrawItem(Control: TWinControl; Index: Integer; 
    Rect: TRect; State: TOwnerDrawState); 
const 
    INDENT = 3; 
begin 
    with TComboBox(Control) do 
    begin 
    FillRect(Canvas.Handle, Rect, GetStockObject(WHITE_BRUSH)); 
    inc(Rect.Left, INDENT); 
    if boolean(Items.Objects[Index]) then 
     SetTextColor(Canvas.Handle, clBlack) 
    else 
     SetTextColor(Canvas.Handle, clGray); 
    DrawText(Canvas.Handle, 
     PChar(Items[Index]), 
     length(Items[Index]), 
     Rect, 
     DT_SINGLELINE or DT_LEFT or DT_VCENTER or DT_END_ELLIPSIS) 
    end; 
end; 

और

procedure TForm1.ComboBox1CloseUp(Sender: TObject); 
begin 
    with TComboBox(Sender) do 
    if (ItemIndex <> -1) and not boolean(Items.Objects[ItemIndex]) then 
    begin 
     beep; 
     Perform(CB_SHOWDROPDOWN, integer(true), 0); 
    end; 
end; 

इसके अलावा, अपने फार्म के इंटरफ़ेस अनुभाग में, प्रपत्र वर्ग की घोषणा करने से पहले,

TComboBox = class(StdCtrls.TComboBox) 
protected 
    procedure WndProc(var Message: TMessage); override; 
end; 

जोड़ सकते हैं और लागू ईवेंट हैंडलर्स जोड़ने WndProc

procedure TComboBox.WndProc(var Message: TMessage); 

    function NextItemIsDisabled: boolean; 
    begin 
    result := (ItemIndex < Items.Count - 1) and 
     not boolean(Items.Objects[ItemIndex + 1]); 
    end; 

    procedure SelectNextEnabledItem; 
    var 
    i: Integer; 
    begin 
    for i := ItemIndex + 1 to Items.Count - 1 do 
     if boolean(Items.Objects[i]) then 
     begin 
     ItemIndex := i; 
     Exit; 
     end; 
    beep; 
    end; 

    procedure KillMessages; 
    var 
    msg: TMsg; 
    begin 
    while PeekMessage(msg, 
     Handle, 
     WM_KEYFIRST, 
     WM_KEYLAST, 
     PM_REMOVE) do; 
    end; 

    function PrevItemIsDisabled: boolean; 
    begin 
    result := (ItemIndex > 0) and 
     not boolean(Items.Objects[ItemIndex - 1]); 
    end; 

    procedure SelectPrevEnabledItem; 
    var 
    i: Integer; 
    begin 
    for i := ItemIndex - 1 downto 0 do 
     if boolean(Items.Objects[i]) then 
     begin 
     ItemIndex := i; 
     Exit; 
     end; 
    beep; 
    end; 

begin 
    case Message.Msg of 
    WM_KEYDOWN: 
     case Message.WParam of 
     VK_DOWN: 
      if NextItemIsDisabled then 
      begin 
      SelectNextEnabledItem; 
      KillMessages; 
      Exit; 
      end; 
     VK_UP: 
      if PrevItemIsDisabled then 
      begin 
      SelectPrevEnabledItem; 
      KillMessages; 
      Exit; 
      end; 
     end; 
    end; 
    inherited; 
end; 

उदाहरण

procedure TForm1.FormCreate(Sender: TObject); 
begin 
    ComboBox1.Items.AddObject('Alpha', TObject(true)); 
    ComboBox1.Items.AddObject('Beta', TObject(true)); 
    ComboBox1.Items.AddObject('Gamma', TObject(false)); 
    ComboBox1.Items.AddObject('Delta', TObject(true)); 
end; 

के लिए कॉम्बो बॉक्स की जांच के लिए लिखते हैं, मुझे लगता है कि तुम यहाँ true और false का अर्थ मिलता है - यह सीधा सा अर्थ enabled

+5

+1, एंड्रियास, हालांकि अगर हम एक साथ काम करते हैं तो मैं आपको शूट करूंगा और आपने इसका इस्तेमाल किया (और मेरे उपयोगकर्ता भी)। वे comboboxes की तरह अभिनय comboboxes के लिए उपयोग किया जाता है। मैंने कोड के करीब कुछ भी पोस्ट नहीं किया; मुझे लगा कि अगर कोई मानकों को बाधित करना चाहता है तो उन्हें कोडिंग को समझने के लिए कुछ काम करना होगा। –

+0

@ केन: मैं शायद इसका उपयोग नहीं करूँगा, लेकिन मैंने इस प्रकार के गैर-मानक comboboxes पिछले और अधिक वर्षों से देखा है, खासकर इंटरनेट पर (एचटीएमएल + सीएसएस + जावास्क्रिप्ट), तो मुझे लगता है कि यह * नहीं है * खराब। –

+0

लेकिन डेस्कटॉप ऐप * विंडोज * है, जिसमें इस सामान के लिए यूआई मानक हैं। एचटीएमएल/सीएसएस/जेएस नहीं - आप जो कुछ भी चाहते हैं वह आप करते हैं। (लेकिन मैंने आपको +1 दिया था, भले ही मैं असहमत हूं - आपका उत्तर मूल प्रश्न के लिए जगह पर था।) :) –

5

यह आसान नहीं है (और यह एक बुरा विचार है, क्योंकि यह नहीं है कि कैसे comboboxes विंडोज पर व्यवहार करते हैं)।

आपको खुद को combobox आकर्षित करना होगा। वस्तुओं को सक्षम या अक्षम किया गया है या नहीं, यह स्टोर करने के लिए आइटम्स.ऑब्जेक्ट्स सरणी का उपयोग करें, और रंगों को उचित रूप से सेट करने के लिए प्रत्येक आइटम को चित्रित करने से पहले उस सरणी को जांचें।

आपको OnChange और OnClick ईवेंट को संभालने की आवश्यकता होगी, और अंतिम चयनित ItemIndex ट्रैक करने के लिए एक तरीका जोड़ें। OnChange/OnClick में, आप ईवेंट हैंडलर को डिस्कनेक्ट करते हैं, Objects[ItemIndex] मान को देखने के लिए कि क्या चयन की अनुमति है, ItemIndex को अंतिम चयनित ItemIndex पर सेट न करें, और फिर ईवेंट हैंडलर को फिर से सक्षम करें।

+4

क्या होता है यदि उपयोगकर्ता गिराए गए कॉम्बो बॉक्स में स्पष्ट रूप से अक्षम आइटम पर क्लिक करता है? बॉक्स बंद हो जाएगा और उपयोगकर्ता को यह नहीं पता होगा कि यह अंतिम चयनित मूल्य पर वापस आ गया है। यह भ्रमित है! –

+0

आप यहां न्यूज ग्रुप में कुछ अतिरिक्त जानकारी पा सकते हैं: http://groups.google.com/group/comp.lang.pascal.delphi.misc/browse_thread/thread/ea67221a7d3f7e13/17418f924fc64f43?lnk=raot&pli=1 – pritaeas

+0

@Cosmin : माना। जैसा कि मैंने कहा, यह नहीं है कि कैसे comboboxes खिड़कियों में काम करते हैं। यही कारण है कि मैंने कहा कि यह एक भयानक विचार है, और आपका बेहतर था।मैंने यह भी कहा कि यह आसान नहीं था। –

0

सिर्फ KeyPress प्रक्रिया

procedure Tform1.Combobox1editKeyPress(Sender: TObject; var Key: Char); 
begin 
    Key:=#0; 
end; 
संबंधित मुद्दे