我已创建了一个自定义BoundField
,可与编辑和插入模式中的DetailsView
一起使用,以利用Twitter Bootstrap。
该控件工作正常,除非我在 InitializeDataCell(...)期间添加额外的LiteralControl
以在TextBox
周围添加一些HTML。与此相关的代码即将结束。
下面生成的HTML似乎与TemplateField
生成的HTML相同。但是,当我触发更新时,只要它在此处添加额外的 div / span ,TextBox
中的值为空在 PostBack 。
<div class="input-prepend">
<span class="add-on">$</span>
<input name="ctl00$ctl00$MainContent$MainContent$pi$dvPackage$tbPrice" type="text" value="0" size="5" id="MainContent_MainContent_pi_dvPackage_tbPrice" title="Price">
</div>
以下是我在前面的ASP.NET代码中正在做的事情以及生成HTML的一些示例。
不起作用 - 自定义字段 通过 Update 命令提交后,文本框内的值将被取消设置,仅当我添加 input-append 和 add-on 部分时。
DetailsView中的字段
<my:ValidationField DataField="Price" HeaderText="Price" TextPrepend="$" />
HTML生成
<td>
<div class="input-prepend">
<span class="add-on">$</span>
<input name="ctl00$ctl00$MainContent$MainContent$pi$dvPackage$tbPrice" type="text" value="0" size="5" id="MainContent_MainContent_pi_dvPackage_tbPrice" title="Price">
</div>
</td>
是否有效 - 正常的TemplateField 工作正常
DetailsView中的字段
<asp:TemplateField>
<EditItemTemplate>
<div class="input-prepend">
<span class="add-on">$</span>
<asp:TextBox ID="tbCost" runat="server" Text='<%# Bind("Cost") %>'></asp:TextBox>
</div>
</EditItemTemplate>
</asp:TemplateField>
生成的HTML - 与上面的内容相同
<td>
<div class="input-prepend">
<span class="add-on">$</span>
<input name="ctl00$ctl00$MainContent$MainContent$pi$dvPackage$tbPrice" type="text" value="0" size="5" id="MainContent_MainContent_pi_dvPackage_tbPrice" title="Price">
</div>
</td>
可行 - 使用自定义字段生成HTML 当我不添加 TextPrepend 字段时,通过 Update 命令正确提交文本框内的值。
DetailsView中的字段
<my:ValidationField DataField="Price" HeaderText="Price" />
生成的HTML没有额外的span / div
<td>
<input name="ctl00$ctl00$MainContent$MainContent$pi$dvPackage$tbPrice" type="text" value="0" size="5" id="MainContent_MainContent_pi_dvPackage_tbPrice" title="Price">
</td>
与此代码创建相关的InitializeDataCell 部分
我认为这是由于 InitializeDataCell(...)实现的原因造成的。
protected override void InitializeDataCell(DataControlFieldCell cell, DataControlRowState rowState)
{
base.InitializeDataCell(cell, rowState);
// Find the text box to validate
TextBox text = FindTextBox(cell);
if (text != null)
{
text.ID = "tb" + DataField;
text.MaxLength = MaxLength;
text.TextMode = TextMode;
text.Text = DataField;
string cellCss = string.Empty;
bool prepend = !string.IsNullOrEmpty(this.TextPrepend);
bool append = !string.IsNullOrEmpty(this.TextAppend);
bool addon = prepend || append;
if (prepend == true)
cellCss = this.ConcatenateCss(cellCss, "input-prepend");
if (append == true)
cellCss = this.ConcatenateCss(cellCss, "input-append");
if (addon == true)
{
int textIndex = cell.Controls.IndexOf(text);
Literal container = new Literal();
container.Text = "<div class=\"" + cellCss + "\">";
cell.Controls.AddAt(textIndex, container);
}
if (prepend == true)
{
int textIndex = cell.Controls.IndexOf(text);
Literal units = new Literal();
units.Text = "<span class=\"add-on\">" + this.Prepend() + "</span>";
cell.Controls.AddAt(textIndex, units);
}
if (append == true)
{
Literal units = new Literal();
units.Text = "<span class=\"add-on\">" + this.Append() + "</span>";
cell.Controls.Add(units);
}
if (addon == true)
{
Literal container = new Literal();
container.Text = "</div>";
cell.Controls.Add(container);
}
}
}
整个代码,以防任何人尝试使用Twitter Bootstrap,或者我的代码在其他地方出错。
public class ValidationField : BoundField
{
#region Properties
public virtual string EditTextCssClass
{
get
{
return (string)(ViewState["EditTextCssClass"] ?? string.Empty);
}
set
{
ViewState["EditTextCssClass"] = value;
OnFieldChanged();
}
}
public virtual ValidatorDisplay ErrorDisplay
{
get
{
return (ValidatorDisplay)(ViewState["ErrorDisplay"] ?? ValidatorDisplay.Dynamic);
}
set
{
ViewState["ErrorDisplay"] = value;
OnFieldChanged();
}
}
public virtual string ErrorMessage
{
get
{
return (string)(ViewState["ErrorMessage"] ?? "Invalid value entered");
}
set
{
ViewState["ErrorMessage"] = value;
OnFieldChanged();
}
}
public virtual string HelpText
{
get
{
return (string)(ViewState["HelpText"] ?? string.Empty);
}
set
{
ViewState["HelpText"] = value;
OnFieldChanged();
}
}
public virtual TwitterBootstrap.WebControls.TextBox.HelpTextDisplayMode HelpDisplay
{
get
{
return (TwitterBootstrap.WebControls.TextBox.HelpTextDisplayMode)(ViewState["HelpDisplay"] ?? TwitterBootstrap.WebControls.TextBox.HelpTextDisplayMode.Block);
}
set
{
ViewState["HelpDisplay"] = value;
OnFieldChanged();
}
}
public virtual int MaxLength
{
get
{
return (int)(ViewState["MaxLength"] ?? 0);
}
set
{
ViewState["MaxLength"] = value;
OnFieldChanged();
}
}
public virtual string PlaceHolder
{
get
{
return (string)(ViewState["PlaceHolder"] ?? string.Empty);
}
set
{
ViewState["PlaceHolder"] = value;
OnFieldChanged();
}
}
public virtual bool Required
{
get
{
return (bool)(ViewState["Required"] ?? false);
}
set
{
ViewState["Required"] = value;
OnFieldChanged();
}
}
public virtual TextBoxMode TextMode
{
get
{
return (TextBoxMode)(ViewState["TextMode"] ?? TextBoxMode.SingleLine);
}
set
{
ViewState["TextMode"] = value;
OnFieldChanged();
}
}
public virtual string ValidationExpression
{
get
{
return (string)(ViewState["ValidationExpression"] ?? string.Empty);
}
set
{
ViewState["ValidationExpression"] = value;
OnFieldChanged();
}
}
public virtual string ValidationGroup
{
get
{
return (string)(ViewState["ValidationGroup"] ?? string.Empty);
}
set
{
ViewState["ValidationGroup"] = value;
OnFieldChanged();
}
}
public virtual string TextAppend
{
get
{
object value = ViewState["TextAppend"];
if (value != null)
return value.ToString();
return string.Empty;
}
set
{
ViewState["TextAppend"] = value;
OnFieldChanged();
}
}
public virtual string TextPrepend
{
get
{
object value = ViewState["TextPrepend"];
if (value != null)
return value.ToString();
return string.Empty;
}
set
{
ViewState["TextPrepend"] = value;
OnFieldChanged();
}
}
#endregion
public ValidationField()
{
}
protected override DataControlField CreateField()
{
return new ValidationField();
}
protected override void InitializeDataCell(DataControlFieldCell cell, DataControlRowState rowState)
{
base.InitializeDataCell(cell, rowState);
// Find the text box to validate
TextBox text = FindTextBox(cell);
if (text != null)
{
text.ID = "tb" + DataField;
text.MaxLength = MaxLength;
text.TextMode = TextMode;
text.CssClass = EditTextCssClass;
text.Text = DataField;
if (PlaceHolder != string.Empty)
text.Attributes.Add("placeholder", PlaceHolder);
string cellCss = string.Empty;
bool prepend = !string.IsNullOrEmpty(this.TextPrepend);
bool append = !string.IsNullOrEmpty(this.TextAppend);
bool addon = prepend || append;
if (prepend == true)
cellCss = this.ConcatenateCss(cellCss, "input-prepend");
if (append == true)
cellCss = this.ConcatenateCss(cellCss, "input-append");
if (addon == true)
{
int textIndex = cell.Controls.IndexOf(text);
Literal container = new Literal();
container.Text = "<div class=\"" + cellCss + "\">";
cell.Controls.AddAt(textIndex, container);
}
if (prepend == true)
{
int textIndex = cell.Controls.IndexOf(text);
Literal units = new Literal();
units.Text = "<span class=\"add-on\">" + this.Prepend() + "</span>";
cell.Controls.AddAt(textIndex, units);
}
if (append == true)
{
Literal units = new Literal();
units.Text = "<span class=\"add-on\">" + this.Append() + "</span>";
cell.Controls.Add(units);
}
if (addon == true)
{
Literal container = new Literal();
container.Text = "</div>";
cell.Controls.Add(container);
}
if (Required == true)
{
Literal required = new Literal();
required.Text = "<span class=\"required\">*</span>";
cell.Controls.Add(required);
}
if (HelpText != string.Empty)
{
Label lblHelpText = new Label();
if (HelpDisplay == TwitterBootstrap.WebControls.TextBox.HelpTextDisplayMode.Block)
lblHelpText.CssClass = "help-block";
else
lblHelpText.CssClass = "help-inline";
lblHelpText.Text = HelpText;
cell.Controls.Add(lblHelpText);
}
if (Required == true)
{
// Add a RequiredFieldValidator
RequiredFieldValidator required = new RequiredFieldValidator();
required.ErrorMessage = ErrorMessage;
required.Display = ErrorDisplay;
required.ControlToValidate = text.ID;
required.Text = "";
if (ValidationGroup != string.Empty)
required.ValidationGroup = ValidationGroup;
cell.Controls.Add(required);
}
if (ValidationExpression != string.Empty)
{
// Add a RequiredFieldValidator
RegularExpressionValidator regex = new RegularExpressionValidator();
regex.ErrorMessage = ErrorMessage;
regex.Display = ErrorDisplay;
regex.ControlToValidate = text.ID;
regex.ValidationExpression = ValidationExpression;
if (ValidationGroup != string.Empty)
regex.ValidationGroup = ValidationGroup;
cell.Controls.Add(regex);
}
}
}
#region Methods
private string ConcatenateCss(params string[] classes)
{
string result = string.Empty;
foreach (string s in classes)
result += s + " ";
return result.TrimEnd().TrimStart();
}
private static TextBox FindTextBox(Control parent)
{
TextBox result = null;
foreach (Control control in parent.Controls)
{
if (control is TextBox)
{
result = control as TextBox;
break;
}
}
return result;
}
protected virtual string Prepend()
{
return this.TextPrepend;
}
protected virtual string Append()
{
return this.TextAppend;
}
#endregion
}
答案 0 :(得分:0)
我设法弄清楚为什么会这样。由于Control
集合在字段中已更改,因此您还必须覆盖_ExtractValuesFromCell(...)to get the
TextBox`值。
我使用了ASP.NET Boundfield overridden to support Dropdownlist is missing one final feature稍微改变的实现,并没有针对我的用例进行优化。但是,它现在工作正常。
public override void ExtractValuesFromCell(System.Collections.Specialized.IOrderedDictionary dictionary, DataControlFieldCell cell, DataControlRowState rowState, bool includeReadOnly)
{
Control control = null;
string dataField = DataField;
object text = null;
string nullDisplayText = NullDisplayText;
if (((rowState & DataControlRowState.Insert) == DataControlRowState.Normal) || InsertVisible)
{
if (cell.Controls.Count > 0)
{
foreach (Control c in cell.Controls)
{
control = cell.Controls[0];
if (c is TextBox)
{
text = ((TextBox)c).Text;
}
}
}
else if (includeReadOnly)
{
string s = cell.Text;
if (s == " ")
{
text = string.Empty;
}
else if (SupportsHtmlEncode && HtmlEncode)
{
text = HttpUtility.HtmlDecode(s);
}
else
{
text = s;
}
}
if (text != null)
{
if (((text is string) && (((string)text).Length == 0)) && ConvertEmptyStringToNull)
{
text = null;
}
if (((text is string) && (((string)text) == nullDisplayText)) && (nullDisplayText.Length > 0))
{
text = null;
}
if (dictionary.Contains(dataField))
{
dictionary[dataField] = text;
}
else
{
dictionary.Add(dataField, text);
}
}
}
}