DCSIMG
Creating RequiredFieldValidator for DetailsView dynamically - שלמה גולדברג (הרב דוטנט)

שלמה גולדברג (הרב דוטנט)

מרצה בסלע ויועץ בעולם ה - net.

Creating RequiredFieldValidator for DetailsView dynamically

 

אחד מהפקדים הנחמדים לעבוד עם מידע הוא ה - DetailsView, הוא יודע להציג מידע לאורך במקום לרוחב (כמו Grid) ומתאים מאוד לעידכון של שורה אחת.
 
בדרך כלל מה שאני עושה זה להציג Grid עם כל הנתונים וכשבוחרים שורה מתוך ה - Grid אני מציג את הנתונים של אותה שורה ב - DetailsView.
 
 
לאחרונה רציתי לעבוד איתו בצורה דינמית כלומר - לא להגדיר מראש ב - aspx את כל העמודות. ורציתי להוסיף לאחד העמודות RequiredFieldValidator. נשמע פשוט לא, אז נראה את הקוד.
 
בהתחלה אני מקשר טבלה (עם שורה אחת) ל DetailsView
 

protected void Page_Load(object sender, EventArgs e)

{

    if (!IsPostBack)

    {

        Bind();

    }

}

 

private void Bind()

{

    DataTable dt = GetTable();

 

    DetailsView1.DataSource = dt;

    DetailsView1.DataBind();

}

 

private DataTable GetTable()

{

    if (Session["table"] == null)

    {

        DataTable dt = new DataTable();

        dt.Columns.Add("Id");

        dt.Columns.Add("Name");

        dt.Columns.Add("Age");

        dt.Columns.Add("Salary");

 

        dt.Rows.Add(1, "Ron", 40, 5000);

 

        Session["table"] = dt;

    }

 

    return (DataTable)Session["table"];

}

 
 
ונרשמתי לאירוע של ModeChanging וכתבתי את הקוד הבא.
 

protected void DetailsView1_ModeChanging(object sender, DetailsViewModeEventArgs e)

{

    DetailsView1.ChangeMode(e.NewMode);

    Bind();

 

    TextBox txtId = DetailsView1.Rows[0].Cells[1].Controls[0] as TextBox;

 

    RequiredFieldValidator rfv = new RequiredFieldValidator();

    rfv.ControlToValidate = txtId.ID;

    rfv.ErrorMessage = "Required";

 

    DetailsView1.Rows[0].Cells[1].Controls.Add(rfv);

}

 
 
כשהרצתי את הקוד הזה קבלתי את התוצאה הבאה.
 
"The ControlToValidate property of '' cannot be blank."
 
כשהסתכלתי ב - debugger ראיתי שאמנם המאפיין ID של txtId הוא null, מה שמעניין שברגע שהסתכלתי ב - watch על המאפיין היה לו ערך. כלומר עם הייתי כותב ב - watch את הדבר הבא - txt.ID הייתי מקבל null אבל עם הייתי כותב txt ומתחיל ללחוץ על סימן ה + כדי לראות את המאפיינים הייתי רואה במאפיין ID ערך (וכמובן שמאותו רגע גם הפקודה txt.ID החזירה ערך. ובמילים אחרות ה - ID של הפקד מתרנדר רק כשמסתכלים ב - watch, (או כשהדף נטען) זה נקודה מאוד לא ברורה ואני אחקור אותה כדי להבין מה קורה כאן, מהסתכלות קטנה ב - reflector אני רואה את הקוד הבא
 

public virtual string ID

{

    get

    {

        if (!this.flags[1] && !this.flags[0x800])

        {

            return null;

        }

        return this._id;

    }

    set

    {

        // ...

    }

}

 
אני לא מבין כרגע למה אם המערך במקום 1 וגם במקום 2048 הוא false הם מחזירים null, וזה נקודה שאני אבדוק בהזדמנות אחרת.
 
הפיתרון שכרגע השתמשתי היה לכתוב את הדבר הבא.
 

protected void DetailsView1_ModeChanging(object sender, DetailsViewModeEventArgs e)

{

    DetailsView1.ChangeMode(e.NewMode);

    Bind();

 

    TextBox txtId = DetailsView1.Rows[0].Cells[1].Controls[0] as TextBox;

 

    RequiredFieldValidator rfv = new RequiredFieldValidator();

 

    string id = txtId.ClientID.Substring(txtId.ClientID.LastIndexOf('_') + 1);

    rfv.ControlToValidate = rfv.ControlToValidate = id;

    rfv.ErrorMessage = "Required";

 

    DetailsView1.Rows[0].Cells[1].Controls.Add(rfv);

}

 
מתברר שהמאפיין ClientID כן מאותחל מראש בערך שלו, אז אני פשוט מוציא ממנו את ה - ID שהפקד יקבל בזמן שהוא יתרנדר.
 
נקודה נוספת שגיליתי (ואני צריך להבין אותה) שחייבים להוסיף את ה - Validator ל - Collection הבא: DetailsView1.Rows[0].Cells[1].Controls
אבל עם ננסה להוסיף את ה - Validator ל - Collection של ה - Form. נקבל את השגיאה הבאה.
 
Control 'ctl01' referenced by the ControlToValidate property of '' cannot be validated.
 
 
אני מקווה שאני אצליח למצוא את הסיבות לשני הדברים.
1. מה המשמעות של הקוד במאפיין ID.
2. למה אי אפשר להוסיף את ה - Validator ל - Collection של ה - Form.
 
 
 
דרך אגב. בקוד של המאפיין ID היה כתוב 0x800, ואני הצגתי את הערך העשרוני שלו 2048. השתמשתי עם השירות של גוגל.
פשוט כתבתי בגוגל: 0x800 in decimal וזה החזיר תוצאה.
ממש נחמד לעבוד איתו כדי להמיר מספרים. כמו
10 in binary
 

תוכן התגובה

Yoav Michaeli כתב/ה:

שלמה שלום,

רעיון נחמד, בזמנו מימשתי משהו כזה תוך ירושה מ:

System.Web.UI.WebControls.BoundField

והוספה של היכולת הנדרשות שים לב שהוספת RequiredFieldValidator היא רק התחחלה,

אחרי זה תרצה גם ולידציה על מספרים וכו'...

שווה לך לבחון את הWeb Dynamic Data שהוא חלק מהפרמווק מגרסה 3.5 SP1

יואב

# July 28, 2009 12:00 PM

שלמה גולדברג כתב/ה:

בהמשך לפוסט הזה , (שהראה איך להוסיף Validator ל - DetailsView שנוצר בצורה דינמית) אני רוצה להדגים איך

# July 28, 2009 2:53 PM
שלח תגובה

(שדה חובה)  

(שדה חובה)  

(אופציונלי)

(שדה חובה) 

Please add 7 and 4 and type the answer here:


Enter the numbers above: