c# winform - איך לעצור אירוע בלחיצת 'דאבל - קליק בdataGridView (1.כותרת נערכה, 2.נפתר)
-
שפה: c# winform
עריכה:
בקצרה:
אני מנסה ליצור אירוע בעת לחיצה על תיבת סימון
והבעיה כשלוחצים 'דאבל-קליק' התהליך אינו מושלם כרצוניבהרחבה:
אני מנסה לבצע פעולה חשבונאית של פיזור סכום בשורות בטבלה
בהתבסס על סכום שקיים ב textBox
החישוב מתבצע בעת שינוי בעמודה מסוג checkBox הנמצאת בתוך dataGridViewבאמצעות הקוד דלהלן:
private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e) { _ = dataGridView1.Enabled = false; if (string.Compare(dataGridView1.CurrentCell.OwningColumn.Name, "choose") == 0) { bool checkBoxStatus = Convert.ToBoolean(dataGridView1.CurrentCell.EditedFormattedValue); if (checkBoxStatus) { if (Convert.ToDouble(dataGridView1.CurrentRow.Cells["debt_balance"].Value) <= Convert.ToDouble(textBox1.Text)) { dataGridView1.CurrentRow.Cells["current_payment"].Value = dataGridView1.CurrentRow.Cells["debt_balance"].Value; textBox1.Text = (Convert.ToDouble(textBox1.Text) - Convert.ToDouble(dataGridView1.CurrentRow.Cells["current_payment"].Value)).ToString(); } else if (Convert.ToDouble(dataGridView1.CurrentRow.Cells["debt_balance"].Value) > Convert.ToDouble(textBox1.Text)) { dataGridView1.CurrentRow.Cells["current_payment"].Value = textBox1.Text; textBox1.Text = "0"; } } else { textBox1.Text = (Convert.ToDouble(textBox1.Text) + Convert.ToDouble(dataGridView1.CurrentRow.Cells["current_payment"].Value)).ToString(); dataGridView1.CurrentRow.Cells["current_payment"].Value = "0"; } } _ = dataGridView1.Enabled = true; }
אממה
שאם אני מסמן את התא לאט ובעדינות בקצב סביר (קצב סביר = אינו דאבל / תלת קליק)
הפעולה מתרחשת בצורה תקינהאבל אם אני מקליק עליו ברצף
הוא מפספס חלק מהלחיצות ומפחית מהסכום המופיע בtextBox שלא לפי התנאי
(הסכום בtextBox פוחת לפי הערך, אבל הסימון נשאר, כך שבלחיצה חוזרת הסכום פוחת שוב)בהתחלה סברתי שאולי קצב ההקלקה יותר מהיר מהחישוב
ולכן הוספתי מייד בהתחלה את dataGridView1.Enabled = false
מה שאמור למנוע את הלחיצה הבאה עד לסיום הריצה
אבל זה עדיין לא עזרהיכן שגיתי?
והתשובה הינה:
private void dataGridView1_CellContentDoubleClick(object sender, DataGridViewCellEventArgs e) { dataGridView1_CellContentClick(sender, e); }
-
@mekev
יפה, בניסוח שלי התשובה היא שאירוע קליק לא מטפל באירועי קליק כפול. כלומר בעת קליק עכבר המחשב ממתין אם יהיה לו חבר ורק בהיעדר קליק נוסף מופעל האירוע של הקליק, אחרת מופעל אירוע של דבל קליק.
(יש מתודה של MouseDown שכוללת כל לחיצה, בלי קשר לאם היא "סמוכה לחברתה").הערות לא קשורות:
א._ = dataGridView1.Enabled = false
למה צריך את ההשמה במשתנה של הקו התחתי?
ב. קצב ההקלקה לא מהיר מהחישוב, התצוגה תמיד תמתין לחישוב ושם פעילות לא תיעשה ברקע למעט אם הטריד של החישוב נפרד המטריד הראשי. לכן הdataGridView1.Enabled = false
מיותר.
ג. ביטויים שמשתמשים בהם יותר מפעם אחת רצוי לשים במשנה הן לביצועים והן לקריאות, לעומת ביטויים שמשתמשים רק פעם אחת שזה בהתאם לנסיבות. לכן את כל ההמרות לdouble כדאי להכין מראש.
ד. אולי יש ייתרון בstring.Compare
, נעלם ממני.הקוד לטעמי:
private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e) { if (dataGridView1.CurrentCell.OwningColumn.Name != "choose") return; var tb1Val = Convert.ToDouble(textBox1.Text); var cellVal = Convert.ToDouble(dataGridView1.CurrentRow.Cells["debt_balance"].Value); if ((bool)dataGridView1.CurrentCell.EditedFormattedValue) { dataGridView1.CurrentRow.Cells["current_payment"].Value = Math.Min(tb1Val, cellVal); textBox1.Text = Math.Max(tb1Val - cellVal, 0).ToString(); } else { textBox1.Text = (tb1Val + cellVal).ToString(); dataGridView1.CurrentRow.Cells["current_payment"].Value = "0"; } }
-
@dovid
ברוח האתגרים וההצפנות השורה בימים האחרונים
זה היה המפתח להבנת השאלה המקורית<חופש>. <ילדים>.<בלאגן>. <עייפות>.<מחשב_נייד_שונה_מהמחשב_הרגיל>.<נטסיק>.
שלחתי את השאלה ברגע של חלשות הדעת
ולאחר שהתפקחתי ראיתי שכבר צבר צפיותבהתלבטות האם למחוק או לערוך
חשבתי שלמחוק לאחר צפייה - אינו מן ההגינות והיושר
אולי ה'מנ-דהו' שצפה יושב כעת לכתוב תשובה, שכידוע לפעמים לוקחת כמה דק'ולכן ערכתי מעט את השאלה
ע"מ שתשאר בצורה מועילה
נ.ב.
א. לקח לי זמן להבין שזה בכלל קשור ל'דאבל - קליק'
היות ולפקד checkBox אין בכלל מאפיין שכזהב. הרווחתי מהשארת השאלה
כי החכמתני כאן במספר נקודות לגבי ה'קליק' והמסתעף
ובפרט בסעיף ג שהתחבטתי בזה בעבר -
תיקון טכני קטן:
private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e) { if (dataGridView1.CurrentCell.OwningColumn.Name != "choose") return; var tb1Val = Convert.ToDouble(textBox1.Text); var cellVal = Convert.ToDouble(dataGridView1.CurrentRow.Cells["debt_balance"].Value); var cellpay = Convert.ToDouble(dataGridView1.CurrentRow.Cells["current_payment"].Value); if ((bool)dataGridView1.CurrentCell.EditedFormattedValue) { dataGridView1.CurrentRow.Cells["current_payment"].Value = Math.Min(tb1Val, cellVal); textBox1.Text = Math.Max(tb1Val - cellVal, 0).ToString(); } else { textBox1.Text = (tb1Val + cellpay).ToString(); dataGridView1.CurrentRow.Cells["current_payment"].Value = "0"; } }
הסיבה שאתה משתמש בקביעות בvar
ולא קורא לילד בשמו (Double)
נובעת מצורכי קריאות גרידא
או שיש בזה תועלות נוספות? -
@mekev צודק, קראתי את הקוד בשטחיות, אז יש עוד תיקון שכעת שמתי לב
private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e) { if (dataGridView1.CurrentCell.OwningColumn.Name != "choose") return; var tb1Val = Convert.ToDouble(textBox1.Text); var debt_balance = Convert.ToDouble(dataGridView1.CurrentRow.Cells["debt_balance"].Value); var current_payment = Convert.ToDouble(dataGridView1.CurrentRow.Cells["current_payment"].Value); if ((bool)dataGridView1.CurrentCell.EditedFormattedValue) { dataGridView1.CurrentRow.Cells["current_payment"].Value = Math.Min(tb1Val, debt_balance); textBox1.Text = Math.Max(tb1Val - current_payment, 0).ToString(); } else { textBox1.Text = (tb1Val + current_payment).ToString(); dataGridView1.CurrentRow.Cells["current_payment"].Value = "0"; } }
הvar אני משתמש בו תמיד כמעט, כי זה נח לי לראות איפה אני מכריז על משתנים.
לפי הספר יש להשתמש בו איפה שמיניה וביה כתוב את סוגו אז זה סתם כפילות. -
התיקון הנוסף שהוא:
if ((bool)dataGridView1.CurrentCell.EditedFormattedValue) { dataGridView1.CurrentRow.Cells["current_payment"].Value = Math.Min(tb1Val, debt_balance); textBox1.Text = Math.Max(tb1Val - current_payment, 0).ToString(); }
מחזיר תוצאה שגויה,
היות שהמשתנה נשאר על ערך 0 ולא עובר השמה מחדש אחרי הכנסת הערךבעקבות
@dovid אמר בc# winform - איך לעצור אירוע בלחיצת 'דאבל - קליק בdataGridView (1.כותרת נערכה, 2.נפתר):
ג. ביטויים שמשתמשים בהם יותר מפעם אחת רצוי לשים במשנה הן לביצועים והן לקריאות, לעומת ביטויים שמשתמשים רק פעם אחת שזה בהתאם לנסיבות
מסקרן אותי מה היית עושה
מצד אחד ניתן להשאיר את זה כמו בהתחלה (אומנם במקרה שבו שולם סכום נמוך מהיתרת חוב הtb1Val - current_payment מחזיר תוצאה שלילית,
אבל הגאונות בחשיבה להעביר את זה לMath. מחזירה תוצאה נכונה )או שלמען הדיוק והסדר היית מאתחל את המשתנה
או מכניס את כל המסלול הארוך בשמו -
@mekev ככה
if ((bool)dataGridView1.CurrentCell.EditedFormattedValue) { current_payment = Math.Min(tb1Val, debt_balance) dataGridView1.CurrentRow.Cells["current_payment"].Value = current_payment; textBox1.Text = Math.Max(tb1Val - current_payment, 0).ToString(); }