TreeView مع مربعات الاختيار وأزرار الراديو

يمثل مكون TTreeView دلفي (الموجود في علامة التبويب لوحة مكون "Win32") نافذة تعرض a قائمة هرمية بالعناصر ، مثل العناوين في المستند ، أو الإدخالات في فهرس ، أو الملفات والأدلة الموجودة قرص.

عقدة شجرة مع خانة اختيار أو زر راديو؟

لا تدعم Delphi TTreeview خانات الاختيار بشكل أصلي ولكن عنصر تحكم WC_TREEVIEW الأساسي يدعمها. يمكنك إضافة مربعات اختيار إلى تريفيو عن طريق تجاوز إجراء CreateParams الخاص بـ TTreeView ، وتحديد نمط TVS_CHECKBOXES لعنصر التحكم. والنتيجة هي أن كل شيء العقد في treeview سيكون لها مربعات اختيار مرفقة بها. بالإضافة إلى ذلك ، لا يمكن استخدام خاصية StateImages بعد الآن لأن WC_TREEVIEW يستخدم قائمة الصور هذه داخليًا لتنفيذ مربعات الاختيار. إذا كنت تريد تبديل مربعات الاختيار ، فسيتعين عليك القيام بذلك باستخدام SendMessage أو ال وحدات ماكرو TreeView_SetItem / TreeView_GetItem من عند CommCtrl.pas. يدعم WC_TREEVIEW مربعات الاختيار فقط ، وليس أزرار الاختيار.

النهج الذي ستكتشفه في هذه المقالة أكثر مرونة: يمكنك الحصول على مربعات اختيار و مختلطة أزرار الراديو مع العقد الأخرى بالطريقة التي تريدها دون تغيير TTreeview أو إنشاء جديد

instagram viewer
صف دراسي منه لجعل هذا العمل. أيضًا ، تقرر بنفسك ما هي الصور التي ستستخدمها في مربعات الاختيار / الأزرار الراديوية ببساطة عن طريق إضافة الصور المناسبة إلى قائمة صور StateImages.

أضف خانة اختيار أو زر راديو

على عكس ما قد تعتقد ، هذا أمر بسيط للغاية لتحقيقه دلفي. فيما يلي الخطوات التي تجعلها تعمل:

  1. قم بإعداد قائمة صور (مكون TImageList في علامة تبويب لوحة ألوان مكون "Win32") لـ TTreeview. خاصية StateImages تحتوي على صور للحالة (الحالات) المحددة وغير المحددة لمربعات الاختيار و / أو أزرار الاختيار.
  2. استدعاء إجراء ToggleTreeViewCheckBoxes (انظر أدناه) في أحداث OnClick و OnKeyDown من treeview. يغير إجراء ToggleTreeViewCheckBoxes StateIndex للعقدة المحددة ليعكس الحالة الحالية المحددة / غير المحددة.

لجعل عرضك أكثر احترافية ، يجب عليك التحقق من مكان النقر على العقدة قبل تبديل صور الحالة: من خلال تبديل العقدة فقط عند النقر على الصورة الفعلية ، لا يزال بإمكان المستخدمين تحديد العقدة دون تغييرها حالة.

بالإضافة إلى ذلك ، إذا كنت لا تريد أن يقوم المستخدمون بتوسيع / ​​طي treeview ، فاتصل بإجراء FullExpand في حدث OnShow للنماذج وقم بتعيين AllowCollapse إلى false في حدث OnCollapsing الخاص بـ treeview.

إليك تنفيذ إجراء ToggleTreeViewCheckBoxes:

إجراء ToggleTreeViewCheckBoxes (
العقدة: TTreeNode ؛
قيد الفحص ،
ج التحقق ،
cRadio غير محدد ،
cRadioChecked: عدد صحيح)؛
فار
tmp: TTreeNode ؛
تبدأ معين (عقدة) ثم بينجيف العقدة. StateIndex = cUnChecked ثم
العقدة. StateIndex: = c تم التحقق منه
آخرإذا العقدة. StateIndex = c محدد ثم
العقدة. StateIndex: = cUnChecked
آخر إذا العقدة. StateIndex = cRadioUnChecked ثم تبدأ
tmp: = العقدة. الأبوين؛
ان لم معين (tmp) ثم
tmp: = TTreeView (العقدة. TreeView) .Items.getFirstNode
آخر
tmp: = tmp.getFirstChild ؛
في حين معين (tmp) دوبجنيف (تمب. StateIndex في
[cRadioUnChecked ، cRadioChecked]) ثم
tmp. StateIndex: = cRadioUnChecked ؛
tmp: = tmp.getNextSibling ؛
النهاية;
العقدة. StateIndex: = cRadioChecked ؛
النهاية; // if StateIndex = cRadioUnCheckedالنهاية; // if Assigned (Node)
النهاية; (* ToggleTreeViewCheckBoxes *)

كما ترى من الكود أعلاه ، يبدأ الإجراء بالعثور على أي عقد مربع الاختيار وتبديلها أو إيقاف تشغيلها. بعد ذلك ، إذا كانت العقدة عبارة عن زر اختيار غير محدد ، فإن الإجراء ينتقل إلى العقدة الأولى على المستوى الحالي ، ويضبط جميع العقد على هذا المستوى إلى cRadioUnchecked (إذا كانت العقد cRadioUnChecked أو cRadioChecked) وتبديل العقدة في النهاية إلى تم فحص cRadio.

لاحظ كيف يتم تجاهل أزرار الاختيار المحددة بالفعل. من الواضح أن هذا يرجع إلى أن زر الاختيار المحدد بالفعل سيتم تبديله إلى وضع عدم التحديد ، تاركًا العقد في حالة غير محددة. بالكاد ما تريده معظم الوقت.

إليك كيفية جعل الشفرة أكثر احترافية: في حدث OnClick في Treeview ، اكتب الرمز التالي لتبديل فقط مربعات الاختيار في حالة النقر على صورة الدولة (يتم تعريف ثوابت cFlatUnCheck و cFlatChecked وغيرها في مكان آخر على أنها فهارس في StateImages قائمة الصور):

إجراء TForm1.TreeView1Click (المرسل: TObject) ؛
فار
P: TPoint ؛
ابدأ
GetCursorPos (P) ؛
P: = TreeView1.ScreenToClient (P) ؛
إذا (htOnStateIcon في
TreeView1.GetHitTestInfoAt (P.X، P.Y)) ثم
ToggleTreeViewCheckBoxes (
TreeView1: مختار ،
cFlatUnCheck ،
تم فحص cFlat ،
cFlatRadioUnCheck ،
cFlatRadioChecked) ؛
النهاية; (* TreeView1Click *)

يحصل الرمز على موضع الماوس الحالي ، ويتحول إلى معاينة الإحداثيات ويتحقق مما إذا تم النقر فوق StateIcon عن طريق استدعاء دالة GetHitTestInfoAt. إذا كان الأمر كذلك ، يتم استدعاء إجراء التبديل.

في الغالب ، تتوقع أن يقوم شريط المسافة بتبديل مربعات الاختيار أو أزرار الاختيار ، لذلك إليك كيفية كتابة حدث TreeView OnKeyDown باستخدام هذا المعيار:

إجراء TForm1.TreeView1KeyDown (
المرسل: الهدف ؛
var key: Word؛
التحول: TShiftState) ؛
تبدأ (المفتاح = VK_SPACE) و
معين (TreeView1.Selected) ثم
ToggleTreeViewCheckBoxes (
TreeView1: مختار ،
cFlatUnCheck ،
تم فحص cFlat ،
cFlatRadioUnCheck ،
cFlatRadioChecked) ؛
النهاية؛ (* TreeView1KeyDown *)

أخيرًا ، إليك كيف يمكن أن تبدو أحداث OnShow الخاصة بالنموذج وأحداث OnChanging في Treeview إذا كنت تريد منع انهيار عقد treeview:

إجراء TForm1.FormCreate (المرسل: TObject) ؛
ابدأ
TreeView1.FullExpand ؛
النهاية; (* FormCreate *)
إجراء انهيار الشجرة.
المرسل: الهدف ؛
العقدة: TTreeNode ؛
فار AllowCollapse: منطقية) ؛
ابدأ
AllowCollapse: = خطأ ؛
النهاية; (* TreeView1Collapsing *)

أخيرًا ، للتحقق مما إذا كانت العقدة محددة أم لا ، ما عليك سوى إجراء المقارنة التالية (في معالج أحداث ButtonClick على سبيل المثال)

إجراء TForm1.Button1Click (المرسل: TObject) ؛
فار
نتيجة منطقية: منطقية
tn: TTreeNode ؛
تبدأ معين (TreeView1.Selected) ثم تبدأ
tn: = TreeView1.Selected ؛
BoolResult: = tn. StateIndex في
[cFlatChecked، cFlatRadioChecked] ؛
Memo1.Text: = tn. نص +
#13#10 +
"محدد:" +
BoolToStr (BoolResult ، True) ؛
النهاية;
النهاية; (* Button1Click *)

على الرغم من أن هذا النوع من الترميز لا يمكن اعتباره مهمًا للغاية للمهمة ، إلا أنه يمكن أن يمنح تطبيقاتك مظهرًا أكثر احترافية وأكثر سلاسة. أيضًا ، باستخدام مربعات الاختيار وأزرار الاختيار بحكمة ، يمكنهم جعل تطبيقك أسهل في الاستخدام. بالتأكيد ستبدو جيدة!

تم التقاط هذه الصورة أدناه من تطبيق تجريبي باستخدام الرمز الموضح في هذه المقالة. كما ترى ، يمكنك بحرية مزج العقد التي تحتوي على مربعات اختيار أو أزرار اختيار مع تلك التي لا تحتوي على أي منها ، على الرغم من أنه لا يجب عليك مزج العقد "الفارغة" مع "خانة الاختيار"(ألق نظرة على أزرار الاختيار في الصورة) لأن هذا يجعل من الصعب جدًا معرفة العقد ذات الصلة.