C# DataControlField中的FindControl
我已经创建了一个自定义DataControlField,它在DetailsView中用于显示可编辑的计划。每个自定义字段都传递了DataSourceID字符串,用于填充用户可以选择的值 如果DetailsView处于编辑模式,它将显示一个DropDownList,让用户从来自SqlDataSource的项目列表中进行选择。在只读模式下,将显示所选值的全名 在只读模式中遇到的问题是,我所拥有的只是传入的SqlDataSource的ID,当尝试将其转换为实际的SqlDataSource对象时,它返回null 我将完整对象放在底部,以防将来对任何人都有用,并尝试这样做 代码前端看起来像这样C# DataControlField中的FindControl,c#,asp.net,C#,Asp.net,我已经创建了一个自定义DataControlField,它在DetailsView中用于显示可编辑的计划。每个自定义字段都传递了DataSourceID字符串,用于填充用户可以选择的值 如果DetailsView处于编辑模式,它将显示一个DropDownList,让用户从来自SqlDataSource的项目列表中进行选择。在只读模式下,将显示所选值的全名 在只读模式中遇到的问题是,我所拥有的只是传入的SqlDataSource的ID,当尝试将其转换为实际的SqlDataSource对象时,它返回
<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>
这里sds对象为null
我的问题是,如何将控件名的字符串转换为带有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
}
好吧,这看起来像是一个完整的黑客,但这里是我如何能够引用SqlDataSource的
Page page = (Page)HttpContext.Current.Handler;
SqlDataSource sds = (SqlDataSource)page.FindControl(this.DataSourceID);
DataView dv = (DataView)sds.Select(DataSourceSelectArguments.Empty);
似乎因为我使用的是母版页,所以普通页面对象在其他区域中并不存在
我愿意接受比整个.Parent.Parent.Parent.Parent事情更好的想法。而不是.Parent.Parent。。。使用:
我得到了完全不同的结果,但是你的方法比我的好得多,所以你得到了答案。非常感谢。
ContentPlaceHolder cph = (ContentPlaceHolder)cell.Parent.Parent.Parent.Parent;
SqlDataSource sds = (SqlDataSource)cph.FindControl("sqlReasonCodes");
DataView dv = (DataView)sds.Select(DataSourceSelectArguments.Empty);
ContentPlaceHolder cph = (ContentPlaceHolder)this.Page.Master.FindControl("ContentPlaceHolderID");