
Items בעזרת Add. בדוגמה משדה טקסט ולחצן מתווספות מטלות לרשימה, והשדה מתנקה ומקבל פוקוס מחדש.Items.Clear() מרוקן את הרשימה.Items מציגה את כל הפריטים, ולולאה על SelectedItems מציגה רק את הנבחרים.foreach על האוסף עצמו גורמת לחריגה, כי האוסף משתנה בזמן הריצה. לולאה קדימה על האינדקסים מדלגת על פריטים, כי האינדקס קופץ אחרי כל מחיקה. הפתרון: לולאה הפוכה, מהאחרון לראשון, עם Items.RemoveAt.Remove מקבל את הפריט עצמו ומשווה אותו בעזרת Equals. RemoveAt מקבל מיקום.SelectedIndex = 0 בעת הטעינה, בונה פריט "Select Area" שמוצג מההתחלה.SelectedIndexChanged הוא האירוע הדיפולטי.CheckedItems מחזיר את הפריטים המסומנים בלבד.CheckOnClick קובעת אם לחיצה אחת מסמנת את הפריט.Columns עם Text ורוחב (Width). DisplayIndex קובע את הסדר.ListViewItem ממערך מחרוזות, כשכל איבר הוא ערך של עמודה, ומוסיפים ל-Items.ToString() של האובייקט. לכן מבצעים Override ל-ToString כדי להציג מידע מותאם. בנוסף, כדי להסיר אובייקט לפי הפריט עצמו, צריך לממש Equals בהתאם למאפיינים של המחלקה.הטקסט המלא של הדקות הראשונות בהרצאה «פקדי רשימה - List» בקורס הווידאו של PracticU – כתוביות בעברית עם זמן התחלה לכל פסקה. כך תוכלו לקרוא ולחפש את הנושאים לפני שמתחילים ללמוד.
אנחנו מגיעים לסדרת פקדים שמה שמשותף לכולם זה שהם מסוגלים להכיל רשימה של פריטים. אלו פקדי רשימה, ליסטינג. אז בואו נפתח פרויקט חדש, כמובן סוג Windows Forms Application, ואנחנו הולכים להסתכל על List Controls.
כאן אנחנו הולכים להכיר סדרה של פקדים שמה שמאופיין בכולם זה שאנחנו יכולים להוסיף לכל אחד סדרה מסוימת של פריטים, ככה שהם יחזיקו ויראו את הפריטים כרשימה אחת.
הרכיב הראשון שאנחנו הולכים לראות נקרא List Box. בואו נשים אותו, ובוא נניח שאני רוצה עכשיו להציג סדרה של מטלות.
בואו נשים את זה כאן, ואני רוצה שתהיה לי את היכולת להוסיף מטלה, למחוק מטלה, להציג את כל המטלות, לבחור סדרת מטלות וכולי. קודם כל נקרא לרכיב הזה LST שזה קיצור של List Task מטלות, עכשיו בואו ניקח תיבת טקסט, ניקח לייבל ונוסיף מטלה חדשה.
נגדיר שהלייבל הזאת היא lst-newtask, יש לנו פה תיבת טקסט txt-newtask, בואו נגדיל את זה, ניקח לחצן btn-addTask.
אוקיי, מה אנחנו עכשיו צריכים לעשות? דבר ראשון, מה שאנחנו צריכים להבין זה שבכל רכיב שמסוגל להציג סדרה של פריטים, כמו הליסטבוקס הזאת, יש אוסף שנקרא Items בואו נסתכל עליו הנה אנחנו רואים אותו כאן קודם כל אנחנו יכולים כבר ב-Design Time לפתוח ולהוסיף כל מיני מטלות אם אנחנו רושמים את הדבר הזה אנחנו כבר רואים את המטלות או את הפריטים השונים לא
משנה מה הם מוצגים לנו בתוך הליסט אבל אנחנו לא נוסיף כרגע מטלות בצורה סטטית אנחנו רוצים להוסיף בצורה דינמית יכולנו לעשות גם וגם כמובן מה אנחנו צריכים לעשות אנחנו צריכים לגשת בקוד לרכיב הליסט ושימו לב שרכיב הליסט יש לו את האוסף אייטמס ובאוסף אייטמס יש לנו פה את הפונקציות add, remove, clear וכולי.
בואו נוסיף את txt.txt.newTask.text בצורה כזאת. הלייבל רק, שמתי לב שהתחילית שלה צריכה להיות מובן lbl.newTask.
בואו נריץ, מטלה ראשונה do something, נוסיף. מטלה שנייה do something else, נוסיף. ואנחנו יכולים לראות גם שאנחנו יכולים להוסיף הרבה ערכים בצורה כזאת.
כל מה שאנחנו מוסיפים מופיע בתוך הליסט. אחלה. כנראה שאנחנו נרצה גם לנקוט את תיבת הטקסט, txt-newtext.clear ולשים בחזרה פוקוס בתוך תיבת הטקסט כך שהסמן יופיע מיידית בתוך תיבת הטקסט ויאפשר למשתמש להוסיף עוד מטלה חדשה בצורה כזאת.
אוקיי, כמה דברים נוספים שיכולים להיות עבור ListBox. אם אנחנו רוצים לבצע איזשהו קליר ולנקות רכיב כזה, בואו ניקח לחצן, אז יש לנו צורך להגיע לליסט, אייטמס, אני קצת קליר, בואו נריץ,
נוסיף כמה מטלות שאנחנו רוצים לצפות בהן, ונלחץ על הלחצן, כולם מתנקות. אוקיי, אם אנחנו רוצים להציג את כל המטלות, כל הפריטים שנמצאים בתוך הליסט בוקס, בואו ניקח לחצן, שואו אול, דאבל קליק, נגיע לקוד, ומה שאנחנו רוצים לעשות זה פשוט לרוץ ולאסוף את כל הפריטים, נניח לסטרינג אחת ואז להציג אותה.
יש לנו פה סטרינג all, נרוץ ב-4 על list items count ונשרשר list items במיקום i. בואו נשרשר את זה עם איזושהי עבידת שורה. נציג את all, נבדוק את זה, נביא קצת תוכנית, נוסיף כמה מטלות, נבצע show all ואני רואה שפשוט רצתי על האוסף והצגתי את הכל.
יכלנו גם לרוץ בלולעת for each כמובן. אין שום בעיה, כל פריט בליסט בוקס הוא בעצם אובג'ק, ולכן אנחנו יכולים פשוט לעשות two-string של הפריט.
אנחנו יכולים לבצע, סליחה, לולעת for each. כרגע כל הפריטים הם סטרינג, אז אין לי בעיה לרוץ עם סטרינג. item in list task.items all, פלוס שווה, אפילו בואו נשרשר את מה שכתוב.
בעצם פלוס שווה אייטם ונשרשר ירידת שורה. אין שום בעיה לרוץ עם for each על כל הפריטים של אותו האוסף. מעולה.
עכשיו יש לנו יכולת לבצע בחירה של פריטים. בואו נסתכל מה זה אומר. בחירה של פריטים אומר שהמשתמש יכול לבצע בחירה פשוט עם קליק בצורה מסוימת על הפריטים עצמם ואנחנו רואים שיש לנו כאן איזשהו מאפיין שנקרא selection mode, כלומר המצב של הבחירה ויש לנו כמה אופציות.
one זה אומר שהמשתמש יכול לבחור פריט אחד none זה אומר שהמשתמש לא יכול לבצע שום בחירה של פריטים multi-simple זה אומר שהמשתמש לוחץ פעם אחת זה בחירה ופעם אחת זה ביטול בחירה multi-extended זה אומר שהמשתמש יכול להשתמש לצורך בחירה גם עם קונטרול וגם עם שיפט בואו נראה את multi-extended שהוא בדרך כלל הנפוץ ביותר
אם אני רוצה לאפשר בחירה של מספר פריטים אני מריץ, אני מכניס ערכים ואני רואה שכשאני מסמן פריט אז הוא כמובן מתבצע סימון לגביו אבל אם אני עכשיו לוחץ על קונטרול וממשיך לסמן אני רואה שיש לי אפשרות גם לבחור מספר פריטים.
מה זה השיפט? אם בחרתי פריט, לחצתי שיפט ובחרתי עוד אחד כל הפריטים מהפריט שנבחר עד אליו ייבחרו.
זה ההבדל בין קונטרול שמאפשר בחירה בודדת לבין שיפט שמאפשר בחירה של סדרה של פריטים. עכשיו, אחרי שיש לנו את היכולת לבחור סדרה של פריטים, מה קורה אם אני רוצה ללכת ולהציג רק את הפריטים שנבחרו?
אני רוצה שהמשתמש יוכל לבחור פריטים מסוימים, ואז לבצע איתם דבר מסוים. בואו ניקח פה לחצן נוסף, קרא לו btn show selected, אגדיל אותו טיפה בכדי לראות את הטקסט, אוקיי, ניקח את הקוד הקודם, נדביק, נוריד את עלולת ה-4 הזאת,
אבל אנחנו לא נרוץ על אייטמס אלא נרוץ על סלקטד אייטמס זה ההבדל בואו לא נקרא לזה all נקרא לזה סלקטד נריץ נוסיף סדרה של פריטים נבצע בחירה של זה זה וזה 2 3 ו5 show selected ואנחנו רואים רק את 2 3 ו5 אחלה בואו נבצע דבר נוסף עם הפריטים שנבחרו בואו נניח שאנחנו רוצים לבצע מחיקה של הפריטים זה טיפה טריקי בואו נקרא ללחצן הזה btn
delete selected למה אני טוען שזה טיפה טריקי בואו נסתכל דבר ראשון אם הייתי עכשיו רוצה לבצע מחיקה קודם כל איך אני בעצם יכול למחוק פריט אז יש לי שתי שיטות אני יכול לגשת לליסט אייטמס ויש לנו כאן רימוב ורימוב את רימוב את מוחק אינדקס מסוים אתם רואים שהוא מקבל את המיקום של הפריט ברשימה
שהמיקום הראשון זה תמיד 0 ומוחק לי את הפריט שנמצא במיקום הזה. רימוב מקבל את הפריט עצמו. מקבל את הפריט עצמו ואז פונקציית רימוב רצה על כל הפריטים ומחפשת איפה הפריט נמצא.
איך היא מבצעת את החיפוש? היא פשוט מנסה להשוות על ידי פונקציית equals. זאת אומרת שאם אנחנו לדוגמה מוסיפים פריטים שהם אובייקטים משלנו אז אנחנו כמובן הולכים לראות את ה-two-string שלהם, אולי תכף נעשה דוגמה כזאת, אבל כאשר אנחנו מבצעים מחיקה והמערכת מחפשת
על ידי פונקציית equals את הפריט עצמו. אז יש לי שתי אפשרויות, או remove או remove at. אבל איך אני מוחק את הפריטים שסומנו? אז אם עכשיו אני בא ואני אומר דבר כזה, אני רץ ב-foreach string item in list task.selected, אני רוצה למחוק רק את הפריטים עצמם שסומנו ואני בא לליסט items.remove הרי יש לי את הפריט, הפריט זה אייטם ברשימה.
מה שהולך לקרות אם אני אריץ את זה זה שאני אחטוף exception מהסיבה שאם אנחנו רצים על איזשהו קולקשן מסוים בלולת for each אסור לנו במהלך הריצה על הקולקשן לשנות את גודל הקולקשן.
בואו נסתכל רגע מה יקרה אם אנחנו נריץ את זה. אז אני מריץ עם קונטרול F5 כרגע. בואו נוסיף סדרה של פריטים. בואו נסמן את זה, את זה ואת זה.
ונבצע delete. ואנחנו רואים שיש לנו פה איזושהי exception. List that this enumerator is bound to has been modified. An enumerator can only be used if the list does not change.
אוקיי. אז אסור לנו לרוץ עם לולת for h. אחלה. בואו נרוץ עם לולת for. אין בעיה.
ואני הולך ומשנה את הקונספט הזה לקונספט של בואו נרוץ עם לולת for listTask.selectedItems.count זה רק המספר של הפריטים שנבחרו listTask.items.remove בואו נסיר את listTask.selectedItems במיקום i ואני טוען שהדבר הזה לא יעבוד בואו נסתכל אני מריץ נוסיף סדרה של פריטים, נסמן את 2, 3 ו-5.
נבצע delete, ושימו לב מה סימנו, סימנו 2, 3 ו-5. אני רואה ש-2 נמחק, 3 לא נמחק ו-5 כן נמחק. כבר יש לנו פה איזשהו באג. אוקיי, אז מה בדיוק הבעיה?
הבעיה היא שכאשר אנחנו ביצענו מחיקה, אז האוסף בעצם הצטמצם. אם האוסף הצטמצם, ומה אנחנו בעצם מחקנו? אנחנו סימנו את 2, 3 ו-5. אם אנחנו נצייר את זה, אנחנו נראה שהיה 1, 2, 3, 4, 5.
זה מה שהיה. אנחנו סימנו את 2, 3 ו-5. 2 זה הדבר הראשון שהתגלה ונמחק, אבל אז האוסף הצטמצם והאינדקס של הלולאה, ה-i של הלולאה, קפץ.
זאת אומרת שאם ה-i היה בהתחלה 0, אחר כך בוא נגיד היה לנו פה דבר כזה, היה 0, 1, 2, 3, 4. זה סומן ונמחק, i קפץ לבא בתור, ל-2, אבל עכשיו זה 1 וזה 2, זה כבר לא סומן, ולכן 3 בעצם התבצע דילוג מעליו.
אז אנחנו רואים שאם אנחנו רוצים לבצע מחיקה של פריטים שסומנו, אנחנו צריכים לפעול בטכניקה קצת שונה. יש כל מיני לולאות שאנחנו יכולים להגדיר, אבל בטח לא לולאה שרצה קדימה, אז מה שנעשה זה פשוט נהפוך את הלולאה.
ניקח לולאה שמתחילה ב-count -1, שזה בעצם הפריט האחרון, נכון? כי הפריטים מתחילים מ-0, אז הפריט האחרון יהיה מספר הפריטים פחות 1, נרוץ כל עוד i גדול שווה ל-0, נרוץ הפוך עם i מינוס מינוס, וניגש ונמחוק כעת את listTask.selectedItems במיקום i. בואו נבדוק את זה.
נריץ את התוכנית, נכניס פה ערכים, ונסמן בדיוק את מה שסימנו מקודם 2 3 ו5 delete selected לכן 2 3 ו5 נמחקו הכל בסדר יכולנו לחילופין לעשות משהו קצת אחר ואפשר למחוק את ה-foreach שלא עובדת כמובן על שינוי אוסף אפשר לרוץ על selected indices ש-indice זה הרבים של אינדקס
כלומר זה אוסף של המיקומים של הפריטים שנבחרו. אם אני רץ על המיקומים אז אני יכול להשתמש ב-remove at ואז אני יכול לגשת ל-selected indices במיקום i.
זאתי שיטה נוספת שאני יכול לבצע מחיקה. remove at מקבלת אינדקס, הנה אנחנו נותנים לה את אחד האינדקסים של הפריטים שנמחקו או שסומנו ליתר דיוק. בואו נריץ, נוסיף בדיוק את אותם פריטים, נסמן את אותם פריטים ונבצע מחיקה.
יש לנו פה אחד, שתיים, שלוש, ארבע וחמש. נסמן את שתיים, שלוש וחמש. delete. ובכן, מה שסימנו נמחק.
אז בעצם אנחנו רואים שהצלחנו לעשות סדרה של פעולות נפוצות מאוד עם listbox. פקד הרשימה הבא שאנחנו הולכים לראות זה ה-combo box.
פקד מאוד מפורסם, מה שהקומובוקס בעצם אומר זה שאנחנו יכולים להציג גם כן רשימה של פריטים אבל הרשימה תמיד מצטמצמת וניתן לראות רק פריט אחד ויחיד זאת אומרת אי אפשר לדוגמה לעשות פה בחירה מרובה אי אפשר לראות הרבה פריטים ולבחור במספר פריטים
זה גם לא המטרה שלו, המטרה שלו זה להציג סדרה של פריטים שהיא תמיד תהיה מצומצמת וכל הזמן רואים רק פריט אחד שנבחר בואו נניח שאנחנו רוצים לאפשר למשתמש לבחור