J
Jakob Lithner
In my application I have a dynamic set of attributes stored in a separate
table. To handle this I created a usercontrol that takes a collection of
attributes. The idea is to show all relevant attibutes and make them editable
for the user. Each attribute has: Name, datatype and value.
I use the datatype to create a dynamic control (TextBox, CheckBox or
DropDownList) and put it in a table cell. It works fine.
The problem is when I want to save the values. I then iterate through my
repeater items and pick up all relevant information. The problem is that the
dynamic controls have disappeared! All controls are found except the ones
with the values.
I looked in the resulting webpage source and find all controls in the proper
place. The ASP generated ID and names look correct.
Any help very much appreciated!
ASPX code:
======================================
<%@ Control Language="C#" AutoEventWireup="true"
CodeBehind="ucAttributeList.ascx.cs"
Inherits="XXX.YYY.Web.AppControls.ucAttributeList" %>
<table>
<tr>
<th>
Name
</th>
<th>
Value
</th>
<th>
DataType
</th>
<th>
Description
</th>
</tr>
<asp:Repeater ID="repAttribute"
OnItemDataBound="repAttribute_ItemDataBound" runat="server">
<ItemTemplate>
<tr>
<td>
<asp:Literal ID="litAttributeDisplayName" runat="server"
/>
<asp:HiddenField ID="AttributeTypeID" runat="server" />
<asp:HiddenField ID="ObjectAttributeID" runat="server" />
</td>
<td id="valueCell" runat="server">
</td>
<td>
<asp:Literal ID="litDataType" runat="server" />
</td>
<td>
<asp:Literal ID="litDescription" runat="server" />
</td>
</tr>
</ItemTemplate>
</asp:Repeater>
<tr>
<td>
</td>
<td>
<asp:Button ID="btnSave" runat="server" Text="Save"
onclick="btnSave_Click" />
</td>
<td>
</td>
<td>
</td>
</tr>
</table>
C# code
======================================
public partial class ucAttributeList : UserControl
{
public new List<Attribute> Attributes
{
get
{
var attributes = new List<Attribute>();
foreach (var item in repAttribute.Items)
{
// Find controls
var repeaterItem = (RepeaterItem)item;
var AttributeTypeID =
(HiddenField)(repeaterItem.FindControl("AttributeTypeID"));
var ObjectAttributeID =
(HiddenField)(repeaterItem.FindControl("ObjectAttributeID"));
var valueCell =
(HtmlTableCell)(repeaterItem.FindControl("valueCell"));
var control = valueCell.FindControl("ctrlValue");
// Create attribute and interpret values
var attribute = new Attribute();
attribute.AttributeTypeID =
int.Parse(AttributeTypeID.Value);
attribute.ObjectAttributeID =
int.Parse(ObjectAttributeID.Value);
if (control is TextBox)
attribute.Value = ((TextBox)control).Text;
else if (control is CheckBox)
attribute.Value = ((CheckBox)control).Checked;
else if (control is DropDownList)
attribute.Value =
int.Parse(((DropDownList)control).SelectedValue);
else
throw new SewsException("Control {0} is not handled",
control.GetType());
attributes.Add(attribute);
}
return attributes;
}
set
{
repAttribute.DataSource = value;
repAttribute.DataBind();
}
}
protected void Page_Load(object sender, EventArgs e)
{
}
protected void repAttribute_ItemDataBound(object sender,
RepeaterItemEventArgs e)
{
switch (e.Item.ItemType)
{
case ListItemType.Item:
case ListItemType.AlternatingItem:
// Interpret data item
var attribute = (Attribute)e.Item.DataItem;
// Find controls
var litAttributeDisplayName =
(Literal)(e.Item.FindControl("litAttributeDisplayName"));
var AttributeTypeID =
(HiddenField)(e.Item.FindControl("AttributeTypeID"));
var ObjectAttributeID =
(HiddenField)(e.Item.FindControl("ObjectAttributeID"));
var valueCell =
(HtmlTableCell)(e.Item.FindControl("valueCell"));
var litDataType =
(Literal)(e.Item.FindControl("litDataType"));
var litDescription =
(Literal)(e.Item.FindControl("litDescription"));
// Display static data
litAttributeDisplayName.Text =
attribute.AttributeType.DisplayName;
AttributeTypeID.Value = attribute.AttributeTypeID.ToString();
ObjectAttributeID.Value =
attribute.ObjectAttributeID.ToString();
litDataType.Text =
attribute.AttributeType.AttributeDataType.Name;
litDescription.Text = attribute.AttributeType.Description;
// Handle dynamic control
AttributeDataTypeEnum dataType =
(AttributeDataTypeEnum)attribute.AttributeType.AttributeDataTypeID;
switch (dataType)
{
case AttributeDataTypeEnum.String:
case AttributeDataTypeEnum.int32:
case AttributeDataTypeEnum.float32:
var textBox = new TextBox();
textBox.ID = "ctrlValue";
textBox.Text = attribute.Value.ToString();
textBox.EnableViewState = true;
valueCell.Controls.Add(textBox);
break;
case AttributeDataTypeEnum.Boolean:
var checkBox = new CheckBox();
checkBox.ID = "ctrlValue";
checkBox.Checked = (bool)attribute.Value;
valueCell.Controls.Add(checkBox);
break;
case AttributeDataTypeEnum.Enum:
var dropDownList = new DropDownList();
dropDownList.ID = "ctrlValue";
dropDownList.DataSource =
AttributeEnumAdapter.GetAttributeEnums(attribute.AttributeTypeID);
dropDownList.DataValueField = "Value";
dropDownList.DataTextField = "Name";
dropDownList.DataBind();
dropDownList.SelectedValue = attribute.ValueText;
valueCell.Controls.Add(dropDownList);
break;
default:
throw new SewsException("AttributeDataType {0} is not
handled", dataType);
}
break;
}
}
/// <summary>
/// Save all values from GUI.
/// </summary>
protected void btnSave_Click(object sender, EventArgs e)
{
using (var dc = Sews2DataContext.CreateInstance())
{
foreach (var attribute in Attributes)
{
var dbAttribute = dc.Attributes.Single(a =>
a.AttributeTypeID == attribute.AttributeTypeID && a.ObjectAttributeID ==
attribute.ObjectAttributeID);
dbAttribute.ValueText = attribute.ValueText;
}
dc.SubmitChanges();
}
}
}
Generated web source:
==================================
<tr>
<td>
Reset to Default
<input type="hidden"
name="ctl00$MajorContent$ucAllocateDOToContainer$myAttributeList$repAttribute$ctl02$AttributeTypeID"
id="ctl00_MajorContent_ucAllocateDOToContainer_myAttributeList_repAttribute_ctl02_AttributeTypeID" value="19" />
<input type="hidden"
name="ctl00$MajorContent$ucAllocateDOToContainer$myAttributeList$repAttribute$ctl02$ObjectAttributeID"
id="ctl00_MajorContent_ucAllocateDOToContainer_myAttributeList_repAttribute_ctl02_ObjectAttributeID" value="0" />
</td>
<td
id="ctl00_MajorContent_ucAllocateDOToContainer_myAttributeList_repAttribute_ctl02_valueCell">
<input
id="ctl00_MajorContent_ucAllocateDOToContainer_myAttributeList_repAttribute_ctl02_ctrlValue"
type="checkbox"
name="ctl00$MajorContent$ucAllocateDOToContainer$myAttributeList$repAttribute$ctl02$ctrlValue" checked="checked" /></td>
<td>
Boolean
</td>
<td>
</td>
</tr>
table. To handle this I created a usercontrol that takes a collection of
attributes. The idea is to show all relevant attibutes and make them editable
for the user. Each attribute has: Name, datatype and value.
I use the datatype to create a dynamic control (TextBox, CheckBox or
DropDownList) and put it in a table cell. It works fine.
The problem is when I want to save the values. I then iterate through my
repeater items and pick up all relevant information. The problem is that the
dynamic controls have disappeared! All controls are found except the ones
with the values.
I looked in the resulting webpage source and find all controls in the proper
place. The ASP generated ID and names look correct.
Any help very much appreciated!
ASPX code:
======================================
<%@ Control Language="C#" AutoEventWireup="true"
CodeBehind="ucAttributeList.ascx.cs"
Inherits="XXX.YYY.Web.AppControls.ucAttributeList" %>
<table>
<tr>
<th>
Name
</th>
<th>
Value
</th>
<th>
DataType
</th>
<th>
Description
</th>
</tr>
<asp:Repeater ID="repAttribute"
OnItemDataBound="repAttribute_ItemDataBound" runat="server">
<ItemTemplate>
<tr>
<td>
<asp:Literal ID="litAttributeDisplayName" runat="server"
/>
<asp:HiddenField ID="AttributeTypeID" runat="server" />
<asp:HiddenField ID="ObjectAttributeID" runat="server" />
</td>
<td id="valueCell" runat="server">
</td>
<td>
<asp:Literal ID="litDataType" runat="server" />
</td>
<td>
<asp:Literal ID="litDescription" runat="server" />
</td>
</tr>
</ItemTemplate>
</asp:Repeater>
<tr>
<td>
</td>
<td>
<asp:Button ID="btnSave" runat="server" Text="Save"
onclick="btnSave_Click" />
</td>
<td>
</td>
<td>
</td>
</tr>
</table>
C# code
======================================
public partial class ucAttributeList : UserControl
{
public new List<Attribute> Attributes
{
get
{
var attributes = new List<Attribute>();
foreach (var item in repAttribute.Items)
{
// Find controls
var repeaterItem = (RepeaterItem)item;
var AttributeTypeID =
(HiddenField)(repeaterItem.FindControl("AttributeTypeID"));
var ObjectAttributeID =
(HiddenField)(repeaterItem.FindControl("ObjectAttributeID"));
var valueCell =
(HtmlTableCell)(repeaterItem.FindControl("valueCell"));
var control = valueCell.FindControl("ctrlValue");
// Create attribute and interpret values
var attribute = new Attribute();
attribute.AttributeTypeID =
int.Parse(AttributeTypeID.Value);
attribute.ObjectAttributeID =
int.Parse(ObjectAttributeID.Value);
if (control is TextBox)
attribute.Value = ((TextBox)control).Text;
else if (control is CheckBox)
attribute.Value = ((CheckBox)control).Checked;
else if (control is DropDownList)
attribute.Value =
int.Parse(((DropDownList)control).SelectedValue);
else
throw new SewsException("Control {0} is not handled",
control.GetType());
attributes.Add(attribute);
}
return attributes;
}
set
{
repAttribute.DataSource = value;
repAttribute.DataBind();
}
}
protected void Page_Load(object sender, EventArgs e)
{
}
protected void repAttribute_ItemDataBound(object sender,
RepeaterItemEventArgs e)
{
switch (e.Item.ItemType)
{
case ListItemType.Item:
case ListItemType.AlternatingItem:
// Interpret data item
var attribute = (Attribute)e.Item.DataItem;
// Find controls
var litAttributeDisplayName =
(Literal)(e.Item.FindControl("litAttributeDisplayName"));
var AttributeTypeID =
(HiddenField)(e.Item.FindControl("AttributeTypeID"));
var ObjectAttributeID =
(HiddenField)(e.Item.FindControl("ObjectAttributeID"));
var valueCell =
(HtmlTableCell)(e.Item.FindControl("valueCell"));
var litDataType =
(Literal)(e.Item.FindControl("litDataType"));
var litDescription =
(Literal)(e.Item.FindControl("litDescription"));
// Display static data
litAttributeDisplayName.Text =
attribute.AttributeType.DisplayName;
AttributeTypeID.Value = attribute.AttributeTypeID.ToString();
ObjectAttributeID.Value =
attribute.ObjectAttributeID.ToString();
litDataType.Text =
attribute.AttributeType.AttributeDataType.Name;
litDescription.Text = attribute.AttributeType.Description;
// Handle dynamic control
AttributeDataTypeEnum dataType =
(AttributeDataTypeEnum)attribute.AttributeType.AttributeDataTypeID;
switch (dataType)
{
case AttributeDataTypeEnum.String:
case AttributeDataTypeEnum.int32:
case AttributeDataTypeEnum.float32:
var textBox = new TextBox();
textBox.ID = "ctrlValue";
textBox.Text = attribute.Value.ToString();
textBox.EnableViewState = true;
valueCell.Controls.Add(textBox);
break;
case AttributeDataTypeEnum.Boolean:
var checkBox = new CheckBox();
checkBox.ID = "ctrlValue";
checkBox.Checked = (bool)attribute.Value;
valueCell.Controls.Add(checkBox);
break;
case AttributeDataTypeEnum.Enum:
var dropDownList = new DropDownList();
dropDownList.ID = "ctrlValue";
dropDownList.DataSource =
AttributeEnumAdapter.GetAttributeEnums(attribute.AttributeTypeID);
dropDownList.DataValueField = "Value";
dropDownList.DataTextField = "Name";
dropDownList.DataBind();
dropDownList.SelectedValue = attribute.ValueText;
valueCell.Controls.Add(dropDownList);
break;
default:
throw new SewsException("AttributeDataType {0} is not
handled", dataType);
}
break;
}
}
/// <summary>
/// Save all values from GUI.
/// </summary>
protected void btnSave_Click(object sender, EventArgs e)
{
using (var dc = Sews2DataContext.CreateInstance())
{
foreach (var attribute in Attributes)
{
var dbAttribute = dc.Attributes.Single(a =>
a.AttributeTypeID == attribute.AttributeTypeID && a.ObjectAttributeID ==
attribute.ObjectAttributeID);
dbAttribute.ValueText = attribute.ValueText;
}
dc.SubmitChanges();
}
}
}
Generated web source:
==================================
<tr>
<td>
Reset to Default
<input type="hidden"
name="ctl00$MajorContent$ucAllocateDOToContainer$myAttributeList$repAttribute$ctl02$AttributeTypeID"
id="ctl00_MajorContent_ucAllocateDOToContainer_myAttributeList_repAttribute_ctl02_AttributeTypeID" value="19" />
<input type="hidden"
name="ctl00$MajorContent$ucAllocateDOToContainer$myAttributeList$repAttribute$ctl02$ObjectAttributeID"
id="ctl00_MajorContent_ucAllocateDOToContainer_myAttributeList_repAttribute_ctl02_ObjectAttributeID" value="0" />
</td>
<td
id="ctl00_MajorContent_ucAllocateDOToContainer_myAttributeList_repAttribute_ctl02_valueCell">
<input
id="ctl00_MajorContent_ucAllocateDOToContainer_myAttributeList_repAttribute_ctl02_ctrlValue"
type="checkbox"
name="ctl00$MajorContent$ucAllocateDOToContainer$myAttributeList$repAttribute$ctl02$ctrlValue" checked="checked" /></td>
<td>
Boolean
</td>
<td>
</td>
</tr>