【发布时间】:2014-05-13 11:18:55
【问题描述】:
所以我有一个List<SettingsValue>,我将用它来填充<table runat="server"> (System.Web.UI.HtmlControls.HtmlTable)。
问题在于,当提交表单时,会使用初始值重新创建字段。然后当我遍历元素时,它们都没有改变。但如果我不重新创建它们,那么检查输入值的代码甚至找不到控件。
我不想通过查询字符串发布数据
我通过调用带有参数“id”的方法GetSettingsFromDatabase 来接收设置。 Id 是具有设置的“应用程序”的键。在页面上有一个组合框,用户可以在其中选择他们希望更改设置的应用程序。当在组合框中选择一个项目时,会发生回发,然后我希望再次调用 LoadSettings()。
HTML - 行:
<tr align="left" valign="top" runat="server">
<th runat="server">
<asp:Label runat="server" Text="{field.Name}" />
</th>
<td runat="server">
<asp:TextBox ID="txt{field.ID}_{field.Name}" runat="server" Text="{value}" />
</td>
</tr>
C# - 模型:
public class SettingsValue
{
public long ID { get; set; }
public long FieldID { get; set; }
public string Value { get; set; }
public string RelatedID { get; set; }
public SettingsField Field { get; set; }
}
public class SettingsField
{
public long ID { get; set; }
public long CategoryID { get; set; }
public string Name { get; set; }
public string DataType { get; set; }
public bool Required { get; set; }
public bool Visible { get; set; }
public SettingsCategory Category { get; set; }
}
public class SettingsCategory
{
public SettingsCategory()
{
Fields = new List<SettingsField>();
}
public long ID { get; set; }
public string Name { get; set; }
public string Provider { get; set; }
public SettingsCategoryType Type { get; set; }
public List<SettingsField> Fields { get; private set; }
}
C# - 行生成:
private void LoadSettings(long id)
{
// The id represents some application that has settings
List<SettingsValue> setting = new List<SettingsValue>();
if (id > 0)
settings = GetSettingsFromDatabase(id);
RenderSettings(settings);
}
private void RenderSettings(List<SettingsValue> settings)
{
table.Rows.Clear();
foreach (var value in settings)
{
var field = value.Field;
var fieldGUI_ID = string.Format("{0}_{1}", field.ID, field.Name);
var row = new HtmlTableRow();
row.Attributes.Add("runat", "server");
row.Align = "left";
row.VAlign = "top";
var th = new HtmlTableCell("th");
th.Attributes.Add("runat", "server");
var td = new HtmlTableCell("td");
td.Attributes.Add("runat", "server");
var input = new TextBox();
input.ID = "txt" + fieldGUI_ID;
input.Text = value.Value;
input.Width = new Unit("305px");
input.Attributes.Add("runat", "server");
var label = new Label();
label.Text = field.Name;
label.Attributes.Add("for", input.ClientID);
th.Controls.Add(label);
row.Cells.Add(th);
td.Controls.Add(input);
row.Cells.Add(td);
table.Rows.Add(row);
}
}
C# - 页面加载
protected void Page_Load( object sender, EventArgs e )
{
if (!Page.IsPostBack )
{
LoadSettings(-1);
}
}
C# - 提交时
我们使用 ComponentArt 库进行回调 <ComponentArt:Callback ID="callSettings" runat="server" OnCallback="callSettings_OnCallback" />,但它与常规 ASP.NET 并没有什么不同。
protected void callSettings_OnCallback( object sender, ComponentArt.Web.UI.CallBackEventArgs e )
{
long id = 421;
List<SettingsValue> settings = GetSettingsFromDatabase(id);
List<SettingsValue> updatedValues = new List<SettingsValue>();
foreach (SettingsField f in fields)
{
var val = GetSettingValueFromInput(f);
if (val != null)
updatedValues.Add(val);
}
UpdateSettingsToDatabase(updatedValues);
}
private SettingsValue GetSettingValueFromInput(SettingsField field)
{
var fieldGUI_ID = "txt" + string.Format("{0}_{1}", field.ID, field.Name);
var res = settings.Single(x => x.FieldID == field.ID);
foreach (HtmlTableRow row in table.Rows)
{
foreach (HtmlTableCell cell in row.Cells)
{
var ctrl = cell.FindControl(fieldGUI_ID);
var input = ctrl as TextBox;
if (ctrl == null || input == null)
continue;
res.Value = input.Text;
return res;
}
}
return res;
}
我查看了其他几个问题,但还没有解决。
【问题讨论】:
标签: c# asp.net viewstate dynamically-generated