Ticket Q252956
Visible to All Users

ITemplate - different templates

created 15 years ago

Hello,
I am trying to build an ASPxGridView that uses different ASPx controls in the editor depending on the type of data being edited (text, Char, List or DateTime. I can't use the EditForm template because the edit controls can't be known at design time.
I am using an unbound column in the grid to display/edit the data item. I am handling the different control types in the grid view's "CellEditorInitialize" event handler.
protected void PDRReferencesGrid_CellEditorInitialize(object sender, ASPxGridViewEditorEventArgs e)
    {
        ASPxGridView gv = (ASPxGridView)sender;
        if (e.Column.FieldName == "PDR_VALUE")
        {
            int key = Convert.ToInt16(e.KeyValue);
            PlaceHolder control = new PlaceHolder();
            control.ID = "PDRPlaceHolder";
            string dataType = Convert.ToString(gv.GetRowValuesByKeyValue(key, "DATA_TYPE_NAME"));
            char required = Convert.ToChar(gv.GetRowValuesByKeyValue(key, "MANDATORY_IND"));
            switch (dataType)
            {
                case "String":
                    ASPxTextBox tb = new ASPxTextBox();
                    tb.ID = "PDRValue";
                    tb.ValidationSettings.RequiredField.IsRequired = required == 'Y';
                    tb.ValidationSettings.ValidateOnLeave = true;
                    tb.ValidationSettings.CausesValidation = tb.ValidationSettings.RequiredField.IsRequired;
                    tb.ValidationSettings.ErrorDisplayMode = ErrorDisplayMode.ImageWithText;
                    tb.ValidationSettings.ErrorText = "Required";
                    control.Controls.Add(tb);
                    break;
                case "Date":
                    ASPxDateEdit de = new ASPxDateEdit();
                    de.ID = "PDRValue";
                    de.ValidationSettings.RequiredField.IsRequired = required == 'Y';
                    control.Controls.Add(de);
                    break;
                case "DateTime":
                    ASPxDateEdit dte = new ASPxDateEdit();
                    ASPxTextEdit tte = new ASPxTimeEdit();
                    dte.ID = "PDRValue_Date";
                    dte.ValidationSettings.RequiredField.IsRequired = required == 'Y';
                    tte.ID = "PDRValue_Time";
                    tte.ValidationSettings.RequiredField.IsRequired = dte.ValidationSettings.RequiredField.IsRequired;
                    control.Controls.Add(dte);
                    control.Controls.Add(tte);
                    break;
                case "Char":
                    ASPxCheckBox cb = new ASPxCheckBox();
                    cb.ID = "PDRValue";
                    cb.ValueUnchecked = 'N';
                    cb.ValueChecked = 'Y';
                    cb.ValidationSettings.RequiredField.IsRequired = required == 'Y';
                    control.Controls.Add(cb);
                    break;
                case "List":
                    List<String> demoList = new List<String>();
                    demoList.Add("A list item for demo");
                    ASPxListBox lb = new ASPxListBox();
                    lb.ID = "PDRValue";
                    lb.ValidationSettings.RequiredField.IsRequired = required == 'Y';
                    lb.DataSource = demoList;
                    lb.DataBind();
                    control.Controls.Add(lb);
                    break;
            }
            e.Editor.Controls.Add(control);
        }
    }
Three questions:

  1. Is this the best place to handle the dynamic control creation?
  2. How do I disable the inclusion of the default TextField presented by the editor when in edit mode (attached)?
  3. Does the gridview only support a single ITemplate interface or could I have added an ITemplate interface at the GridViewEditCell level? Something like:
       public class StringEditFormTemplate : ITemplate
        {
            public void InstantiateIn(Control container)
            {
                ASPxTextBox tb = new ASPxTextBox();
                tb.ID = "PDRValue_String";
                container.Controls.Add(tb);
            }
        }
        public class DateEditFormTemplate : ITemplate
        {
            public void InstantiateIn(Control container)
            {
                ASPxDateEdit de = new ASPxDateEdit();
                de.ID = "PDRValue_Date";
                container.Controls.Add(de);
            }
        }
        public class DateTimeEditFormTemplate : ITemplate
        {
            public void InstantiateIn(Control container)
            {
                ASPxDateEdit de = new ASPxDateEdit();
                ASPxTimeEdit te = new ASPxTimeEdit();
                de.ID = "PDRValue_Date";
                te.ID = "PDRValue_Time";
                container.Controls.Add(de);
                container.Controls.Add(te);
            }
        }
        public class CharEditFormTemplate : ITemplate
        {
            public void InstantiateIn(Control container)
            {
                ASPxCheckBox cb = new ASPxCheckBox();
                cb.ID = "PDRValue_Char";
                container.Controls.Add(cb);
            }
        }
        public class ListEditFormTemplate : ITemplate
        {
            public void InstantiateIn(Control container)
            {
                DropDownList ddl = new DropDownList();
                ddl.ID = "PDRValue_List";
                container.Controls.Add(ddl);
            }
        }
Show previous comments (1)

    Thanks for your very fast reply.
    I considered both creating all controls in the unbound column as well as creating a single ITemplate class that predefines the controls but didn't want the overhead associated with hiding those controls I didn't want (I only need one per edit row).
    If I'm understanding your solution correctly, the best method is to create a class implementing the ITemplate interface and adding all controls to this class? Is this any different than adding the controls to the edit form in terms of rendering perfromance?
    When I added the following code, the new editform interface didn't render (either inline or editform)
        protected void PDRReferencesGrid_Init(object sender, EventArgs e)
        {
            ASPxGridView gv = (ASPxGridView)sender;
            gv.Templates.EditForm = new PDRReferencesEditFormTemplate();
        }
        public class PDRReferencesEditFormTemplate : ITemplate
        {
            public void InstantiateIn(Control container)
            {
                ASPxDateEdit de = new ASPxDateEdit();
                de.ID = "PDRValue_Date";
                container.Controls.Add(de);
                AddControls(container);
            }
            protected void AddControls(Control container){
                AddTextBox(container);
                AddDateEdit(container);
                AddTimeEdit(container);
                AddCheckBox(container);
                AddListBox(container);
            }
            protected void AddTextBox(Control container)
            {
                ASPxTextBox tb = new ASPxTextBox();
                tb.ID = "PDRValue_String";
                container.Controls.Add(tb);
            }
            protected void AddDateEdit( Control container)
            {
                ASPxDateEdit de = new ASPxDateEdit();
                de.ID = "PDRValue_Date";
                container.Controls.Add(de);
            }
            protected void AddTimeEdit( Control container)
            {
                ASPxTimeEdit te = new ASPxTimeEdit();
                te.ID = "PDRValue_Time";
                container.Controls.Add(te);
            }
            protected void AddCheckBox( Control container)
            {
                ASPxCheckBox cb = new ASPxCheckBox();
                cb.ID = "PDRValue_Char";
                container.Controls.Add(cb);
            }
            protected void AddListBox( Control container)
            {
                DropDownList ddl = new DropDownList();
                ddl.ID = "PDRValue_List";
                container.Controls.Add(ddl);
            }
        }

      Sorry, the last code snippet for the ITemplate interface included a temp code snippet for debugging. Please swap out the code in the InstantiateIn method with the call to AddControls(container).
      Thanks.

        Should just have ;
                public void InstantiateIn(Control container)
                {
                    AddControls(container);
                }

        Answers

        created 15 years ago

        Grant,
        Based on your scenario, I decided to create a small example, which implements your task.
        Please take a look at the attached project, and let me know if it makes sense for you.
        Thanks,
        Vest

          Show previous comments (3)

            Finalizing legacy SR's

              Hi,
              I have similar issue, but using the GridViewDataItemTemplateContainer. How do you iterate every rows and get the value? The new control returns null for me. I really appreciate your help on this.

              Thanks,
              Phong

              public class CustomTemplate : ITemplate
                  {
                      public void InstantiateIn(Control container)
                      {
                          AddControls(container);
                      }

              protected void AddControls(Control container)
                      {
                          GridViewDataItemTemplateContainer editingContainer = (GridViewDataItemTemplateContainer)container;
                          ASPxGridView gv = (ASPxGridView)editingContainer.Grid;
                          int key = Convert.ToInt16(editingContainer.KeyValue);

              string dataType = Convert.ToString(gv.GetRowValuesByKeyValue(key, "DataType"));

              switch (dataType.ToLower())
                          {
                              case "text":
                                  AddTextBox(container);
                                  break;
                              case "date":
                                  AddDateEdit(container);
                                  break;
                              case "boolean":
                                  AddCheckBox(container);
                                  break;
                              case "integer":
                                  AddSpinEdit(container);
                                  break;
                              case "decimal":
                                  AddTextBox(container);
                                  break;
                          }
                      }

              protected void AddTextBox(Control container)
                      {
                          ASPxTextBox tb = new ASPxTextBox();
                          tb.ID = "edValue";
                          tb.ValidationSettings.ValidateOnLeave = true;
                          container.Controls.Add(tb);
                      }

              protected void AddDateEdit(Control container)
                      {
                          ASPxDateEdit de = new ASPxDateEdit();
                          de.ID = "edValue";
                          container.Controls.Add(de);
                      }

              protected void AddCheckBox(Control container)
                      {
                          ASPxCheckBox cb = new ASPxCheckBox();
                          cb.ID = "edValue";
                          cb.ValueUnchecked = false;
                          cb.ValueChecked = true;
                          container.Controls.Add(cb);
                      }

              protected void AddSpinEdit(Control container)
                      {
                          ASPxSpinEdit tb = new ASPxSpinEdit();
                          tb.ID = "edValue";
                          tb.ValidationSettings.ValidateOnLeave = true;
                          container.Controls.Add(tb);
                      }
                  }

              protected void gvItemAttribute_CellEditorInitialize(object sender, EventArgs e)
                      {
                          ASPxGridView gvItemAttribute = (ASPxGridView)sender;
                          ((GridViewDataColumn)gvItemAttribute.Columns["AttributeValue"]).DataItemTemplate = new CustomTemplate();
                      }

              protected void btnSaveChanges_Click(object sender, EventArgs e)
                      {
                          try
                          {
                              for (int i = 0; i <= (gvItemAttribute.VisibleRowCount - 1); i++)
                              {
                                  var edDatatype = gvItemAttribute.GetRowValues(i, "DataType").ToString();
                                  var edValue = gvItemAttribute.GetRowValues(i, "edValue");   //always return null
                              }
                          }
                          catch (Exception ex)
                          {
                          }
                      }

              Vova (DevExpress Support) 6 years ago

                Hello,

                I've created a separate ticket on your behalf (T692348: ASPxGridView - How to get a value from the controls inside the Data Item template). It has been placed in our processing queue and will be answered shortly.

                Disclaimer: The information provided on DevExpress.com and affiliated web properties (including the DevExpress Support Center) is provided "as is" without warranty of any kind. Developer Express Inc disclaims all warranties, either express or implied, including the warranties of merchantability and fitness for a particular purpose. Please refer to the DevExpress.com Website Terms of Use for more information in this regard.

                Confidential Information: Developer Express Inc does not wish to receive, will not act to procure, nor will it solicit, confidential or proprietary materials and information from you through the DevExpress Support Center or its web properties. Any and all materials or information divulged during chats, email communications, online discussions, Support Center tickets, or made available to Developer Express Inc in any manner will be deemed NOT to be confidential by Developer Express Inc. Please refer to the DevExpress.com Website Terms of Use for more information in this regard.