Ticket Q432101
Visible to All Users
Duplicate

We have closed this ticket because another page addresses its subject:

ASPxGridListEditor - Support the Batch Edit Mode

How to create a custom ITemplate based on controls provided by built-in XAF PropertyEditors

created 12 years ago

Hello,

I am trying to create a Template for User to do batch editing in ListView.

And I handled DateTime Field / number / ENUM / string fields successfully,
but now I want to create ASPxLookupPropertyEditor for Reference fields, but I don't know how to do this.
Could you help giving me some hint? My template code are as follow:

/// <summary>
/// Defines the behavior for populating a templated ASP.NET control in Detail (Data Item) of ListView
/// </summary>
public class fcxDataRowTemplate : ITemplate
{
#region Constant Variables
const string CONTROL_ID_FOR_OID = "lblOid";
const string CONTROL_ID_FOR_VALUE = "txbDisplayValue";
#endregion

#region Local Variables
private ObjectSpace objectSpace;
private Type objectType;
private int rowCount;
public ASPxTextBoxBase ctlDisplayValue;
#endregion

#region Constructors
public fcxDataRowTemplate(ObjectSpace objectSpace, Type objectType)
{
this.objectSpace = objectSpace;
this.objectType = objectType;
}
#endregion

#region ITemplate Methods
void ITemplate.InstantiateIn(Control container)
{
GridViewDataItemTemplateContainer gridViewContainer = container as GridViewDataItemTemplateContainer;
WebDataSource dataSource = gridViewContainer.Grid.DataSource as WebDataSource;
ProxyCollection collection = dataSource.Collection as ProxyCollection;

//Create Table for container of templated controls
Table table = CreateControlsinTable(gridViewContainer);
//Add Table to controls
container.Controls.Add(table);

if (collection != null)
{
//Count the number of object in current page of list view
rowCount = collection.Count;
}
}
#endregion

#region fcxDetailsTemplate Methods
private Table CreateControlsinTable(GridViewDataItemTemplateContainer gridViewContainer)
{
//object o = gridViewContainer.DataItem;
//Create ASPxLabel control to store the Oid of object
ASPxLabel lblOid = RenderHelper.CreateASPxLabel();
lblOid.ID = CONTROL_ID_FOR_OID;
lblOid.Text = gridViewContainer.KeyValue.ToString();
lblOid.Visible = false;
//Create control by corresponding type to store the member value of object
CreateControlForObjectMember(gridViewContainer.Column.FieldName);
ctlDisplayValue.ID = CONTROL_ID_FOR_VALUE;
ctlDisplayValue.Text = gridViewContainer.Text;
//Create Table for container of templated controls
Table table = new Table();
table.Rows.Add(new TableRow());
table.Rows[0].Cells.Add(new TableCell());
table.Rows[0].Cells.Add(new TableCell());
table.Rows[0].Cells[0].Controls.Add(lblOid);
table.Rows[0].Cells[1].Controls.Add(ctlDisplayValue);
//To prevent CallBack from being sent
table.Attributes["onclick"] = RenderHelper.EventCancelBubbleCommand;
return table;
}

private void CreateControlForObjectMember(string memberType)
{
//IMemberInfo memberInfo = XafTypesInfo.Instance.FindTypeInfo(objectType).FindMember(gridViewContainer.Column.FieldName);
IMemberInfo memberInfo = XafTypesInfo.Instance.FindTypeInfo(objectType).FindMember(memberType);

if (memberType.Contains("."))
{
memberInfo = XafTypesInfo.Instance.FindTypeInfo(objectType).FindMember(memberType.Split('.')[0]);
}

if (memberInfo.MemberType == typeof(DateTime))
{
ctlDisplayValue = RenderHelper.CreateASPxDateEdit();
}
else if ((memberInfo.MemberType == typeof(decimal)) || (memberInfo.MemberType == typeof(int)) || (memberInfo.MemberType == typeof(double)))
{
ctlDisplayValue = RenderHelper.CreateASPxSpinEdit();
}
else if (memberInfo.MemberType.BaseType.Name == "Enum")
{
ctlDisplayValue = RenderHelper.CreateASPxComboBox();
((ASPxComboBox)ctlDisplayValue).DataSource = Enum.GetNames(memberInfo.MemberType);
((ASPxComboBox)ctlDisplayValue).DataBind();
}
else if (memberInfo.MemberType.BaseType == typeof(BaseObject))
{
//I would like to create a ASPxLookupPropertyEditor here
}
else
{
ctlDisplayValue = RenderHelper.CreateASPxTextBox();
}
}
#endregion
}

Thank you very much for your help!

Answers

created 12 years ago (modified 12 years ago)

Hello,
It is better to use the methods provided by the EditorsFactory class, because it is a universal solution:
Here is some example code from our sources:

C#
... ViewItem propertyEditorCandidate = helper.Application.EditorFactory.CreateDetailViewEditor(false, modelMemberViewItem, typeof(ParametersObject), helper.Application, helper.ObjectSpace); ...

You can consider creating a separate ObjectSpace via the Application.CreateObjectSpace method for this, instead of using the one provided by the helper object.
Your CreateControlForObjectMember method should return the PropertyEditor's Control instead of being void. So, you can access the Control property of the editor you instantiated. Force its creation via the PropertyEditor.CreateControl method, if necessary. Take special note that you can set the PropertyEditor.ViewEditMode property before your PropertyEditor's control is created, to control whether the control should be in the Edit or View mode. Additionally, setting the PropertyEditor.CurrentObject property is also required before the control is created (e.g., gridViewContainer.Grid.GetRow(gridViewContainer.VisibleIndex)).
Finally, you can consider setting the WebPropertyEditor.SetControlId to avoid problems when multiple controls with the same Id are created for templates.
After that, you can use this control in your custom template. However, note that these approaches are undocumented and you should use them at your own risk. Please be sure to check the framework sources for more information on these classes or recompile the framework's sources to effectively debug problems.
In addition, I recommend you check out the following tickets:
XAF Web: GridView EditForm : "Cannot access a disposed object."
XAF Web: GridView EditFormTemplate with manually generated column editors fails on Update or Cancel
as they describe how to avoid other problems when building custom templates. I hope you find this information helpful.

    Show previous comments (10)
    Dennis Garavsky (DevExpress) 12 years ago

      Normally, there is already a respective code in the base class that binds editors to data:

      C#
      public abstract class ASPxPropertyEditor : WebPropertyEditor, ITestable { private void Editor_Load(object sender, EventArgs e) { ASPxEditor.Load -= new EventHandler(Editor_Load); ASPxEditor.DataBind(); }

      I am not sure though that it is executed in your particular case. It is best to recompile our source code and debug this case to find why it is not working as expected.
      In addition, I recommend you check out the following tickets:
      XAF Web: GridView EditForm : "Cannot access a disposed object."
      XAF Web: GridView EditFormTemplate with manually generated column editors fails on Update or Cancel
      as they describe how to avoid other problems when building custom templates. I hope you find this information helpful.

        Hi Dennis,
        Finally~ I figure it out. I need to set the current object for the property editor before creating control to make it work
                        propertyEditor.CurrentObject = gridViewContainer.Grid.GetRow(gridViewContainer.VisibleIndex);
        Thank you very much for your help

        Dennis Garavsky (DevExpress) 12 years ago

          Hello Edmund,
          I have updated my original answer to include full information about possible difficulties when implementing custom templates based on controls created by XAF editors. Hopefully, it will save time for other support center users implementing the same task.
          Once your question has been resolved to your satisfaction, mark the corresponding answer as a Solution. Your question status will immediately become Closed.
          http://devexpress.com/Support/Center/FAQ

          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.