FindControl within DataControlField
本文关键字:DataControlField within FindControl | 更新日期: 2024-10-18 19:59:17
我创建了一个自定义DataControlField
,用于DetailsView
以显示可编辑的时间表。每个自定义字段都传递了DataSourceID字符串,用于填充用户可以选择的值。
如果DetailsView处于编辑模式,它将显示一个DropDownList
,让用户从来自SqlDataSource
的项目列表中进行选择。在ReadOnly模式中,显示所选值的全名。
我在ReadOnly模式中遇到的问题是,我所拥有的只是传入的SqlDataSource的ID,当试图将其转换为实际的SqlDataSources对象时,它会返回null。
我已经把整个对象放在底部,以防将来对任何人有用,并尝试这样做。
代码前端看起来像这个
<asp:DetailsView ID="dvPayPeroid1" runat="server"
AutoGenerateRows="False"
CssClass="DetailsView"
DataSourceID="sqlMyScheduleData"
DefaultMode="ReadOnly"
GridLines="None">
<FieldHeaderStyle CssClass="DetailsViewHeader" />
<Fields>
<asp:BoundField DataField="FirstDayOfWeek" HeaderText="Week Starting" HtmlEncode="false" DataFormatString="{0:MM/dd/yyyy}" ReadOnly="true" />
<my:ScheduleField DataField="1" HeaderText="Sunday" DataSourceID="sqlReasonCodes" />
<my:ScheduleField DataField="2" HeaderText="Monday" DataSourceID="sqlReasonCodes" />
<my:ScheduleField DataField="3" HeaderText="Tuesday" DataSourceID="sqlReasonCodes" />
<my:ScheduleField DataField="4" HeaderText="Wednesday" DataSourceID="sqlReasonCodes" />
<my:ScheduleField DataField="5" HeaderText="Thursday" DataSourceID="sqlReasonCodes" />
<my:ScheduleField DataField="6" HeaderText="Friday" DataSourceID="sqlReasonCodes" />
<my:ScheduleField DataField="7" HeaderText="Saturday" DataSourceID="sqlReasonCodes" />
<asp:BoundField DataField="FirstDayOfSecondWeek" HeaderText="Week Starting" HtmlEncode="false" DataFormatString="{0:MM/dd/yyyy}" ReadOnly="true" />
<my:ScheduleField DataField="8" HeaderText="Sunday" DataSourceID="sqlReasonCodes" />
<my:ScheduleField DataField="9" HeaderText="Monday" DataSourceID="sqlReasonCodes" />
<my:ScheduleField DataField="10" HeaderText="Tuesday" DataSourceID="sqlReasonCodes" />
<my:ScheduleField DataField="11" HeaderText="Wednesday" DataSourceID="sqlReasonCodes" />
<my:ScheduleField DataField="12" HeaderText="Thursday" DataSourceID="sqlReasonCodes" />
<my:ScheduleField DataField="13" HeaderText="Friday" DataSourceID="sqlReasonCodes" />
<my:ScheduleField DataField="14" HeaderText="Saturday" DataSourceID="sqlReasonCodes" />
</Fields>
</asp:DetailsView>
<asp:SqlDataSource ID="sqlReasonCodes" runat="server"
CacheDuration="500"
ConnectionString="<%$ ConnectionStrings:MyConnectionString %>"
EnableCaching="true"
SelectCommand="ReasonSelectActive" SelectCommandType="StoredProcedure">
</asp:SqlDataSource>
当我将DetailsView设置为编辑模式时,效果非常好。如果is失败,则处于ReadOnly模式,该模式在DataField属性中传递,其值为"P"表示"PTO","W"表示"Working","R"表示"Requested Day Off"等。
我的问题是将DataField转换为相应的长名称。目前,我正在使用这段代码来获取SqlDataSource。
Page page = (Page)HttpContext.Current.Handler;
SqlDataSource sds = (SqlDataSource)page.FindControl(this.DataSourceID);
DataView dv = (DataView)sds.Select(DataSourceSelectArguments.Empty);
此处sds对象为空。
我的问题是,如何将Control名称的字符串转换为具有DataControlField的对象?
下面的代码供参考,如果有人对代码有改进建议,一定要告诉我。
public class ScheduleField : DataControlField
{
#region Properties
public string CssClass
{
get
{
object value = ViewState["CssClass"];
if (value != null)
return value.ToString();
return "MetricStatus";
}
set
{
ViewState["CssClass"] = value;
OnFieldChanged();
}
}
public string DataSourceID
{
get
{
object value = ViewState["DataSourceID"];
if (value != null)
return Convert.ToString(value);
return "";
}
set
{
ViewState["DataSourceID"] = value;
OnFieldChanged();
}
}
public string DataField
{
get
{
object value = ViewState["DataField"];
if (value != null)
return Convert.ToString(value);
return "";
}
set
{
ViewState["DataField"] = value;
OnFieldChanged();
}
}
#endregion
#region Constructors
public ScheduleField()
{
}
#endregion
#region Abstract / Override Implementations
protected override DataControlField CreateField()
{
return new BoundField();
}
public override void InitializeCell(DataControlFieldCell cell, DataControlCellType cellType, DataControlRowState rowState, int rowIndex)
{
base.InitializeCell(cell, cellType, rowState, rowIndex);
// add controls to the cell here.
if (cellType == DataControlCellType.DataCell)
{
if ((rowState & DataControlRowState.Edit) > 0)
cell.DataBinding += new EventHandler(cell_DataBinding_Edit);
else if (rowState == DataControlRowState.Normal || rowState == DataControlRowState.Alternate)
cell.DataBinding += new EventHandler(cell_DataBinding_Normal);
else
throw new Exception("Unhandled rowState: " + rowState.ToString());
}
}
#endregion
#region Events
private void cell_DataBinding_Edit(object sender, EventArgs e)
{
DataControlFieldCell cell = (DataControlFieldCell)sender;
object dataItem = DataBinder.GetDataItem(cell.NamingContainer);
string sDataField = DataBinder.GetPropertyValue(dataItem, DataField).ToString();
DropDownList ddlReason = new DropDownList();
ddlReason.Items.Add(new ListItem("<none>", ""));
ddlReason.AppendDataBoundItems = true;
ddlReason.DataSourceID = this.DataSourceID;
ddlReason.DataTextField = "Name";
ddlReason.DataValueField = "Short";
ddlReason.SelectedValue = sDataField;
cell.Controls.Add(ddlReason);
}
private void cell_DataBinding_Normal(object sender, EventArgs e)
{
DataControlFieldCell cell = (DataControlFieldCell)sender;
object dataItem = DataBinder.GetDataItem(cell.NamingContainer);
string sDataField = DataBinder.GetPropertyValue(dataItem, DataField).ToString();
Page page = (Page)HttpContext.Current.Handler;
SqlDataSource sds = (SqlDataSource)page.FindControl(this.DataSourceID);
DataView dv = (DataView)sds.Select(DataSourceSelectArguments.Empty);
DataTable dt = dv.ToTable();
foreach (DataRow dr in dt.Rows)
{
if (dr["Short"].ToString() == sDataField)
sDataField = dr["Name"].ToString();
}
Label lblReason = new Label();
lblReason.Text = sDataField;
cell.Controls.Add(lblReason);
}
#endregion
#region Methods
// no methods
#endregion
}
代替.parent.parent
。。。用途:
ContentPlaceHolder cph = (ContentPlaceHolder)this.Page.Master.FindControl("ContentPlaceHolderID");
好吧,这看起来像是一个完整的破解,但以下是我如何引用SqlDataSource
的。
ContentPlaceHolder cph = (ContentPlaceHolder)cell.Parent.Parent.Parent.Parent;
SqlDataSource sds = (SqlDataSource)cph.FindControl("sqlReasonCodes");
DataView dv = (DataView)sds.Select(DataSourceSelectArguments.Empty);
由于我使用的是MasterPage
,所以在其他区域中,普通的Page对象似乎并不存在。
我愿意接受比.Parent.Parent.Parent.Parent
更好的想法。