2012-08-06 4 views
1

J'ai créé une coutume DataControlField qui est utilisé dans un DetailsView pour afficher un calendrier modifiable. La chaîne DataSourceID transmise à chacun de ces champs personnalisés est utilisée pour renseigner les valeurs qu'un utilisateur peut choisir.FindControl au sein DataControlField

Si le DetailsView est en mode Modifier , il affichera un DropDownList de laisser l'utilisateur choisir parmi une liste d'éléments qui viennent d'un SqlDataSource. En ReadOnly mode, il est d'afficher le nom complet de la valeur sélectionnée.

Le problème que j'ai en mode ReadOnly est que tout ce que j'ai est l'ID du SqlDataSource passé et en essayant de le convertir en un objet SqlDataSource réelle, elle renvoie null.

J'ai mis l'objet complet au fond dans le cas où il est utile à tout le monde à l'avenir, en essayant de le faire aussi bien.

Le front de code ressemble à ceci

<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> 

Quand je place le DetailsView en mode Edit, il fonctionne très bien. Où est l'échec est en mode ReadOnly qui est transmis dans la propriété DataField avec des valeurs telles que «P» pour «PTO», «W» pour «travail», «R» pour «jour de repos demandé», etc.

Mon problème est de convertir le DataField en son nom long correspondant. Actuellement, j'utilise ce bit de code pour récupérer le SqlDataSource.

Page page = (Page)HttpContext.Current.Handler; 
SqlDataSource sds = (SqlDataSource)page.FindControl(this.DataSourceID); 
DataView dv = (DataView)sds.Select(DataSourceSelectArguments.Empty); 

Ici, le sds objet est nul.

Ma question est, comment puis-je convertir la chaîne d'un nom de contrôle à un objet avec un DataControlField?

code

est ci-dessous pour référence et si quelqu'un a une suggestion d'amélioration du code de la route, ne dites.

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 
} 

Répondre

3

Au lieu de .parent.parent ... Utilisation:

ContentPlaceHolder cph = (ContentPlaceHolder)this.Page.Master.FindControl("ContentPlaceHolderID"); 
+0

J'ai fini avec quelque chose de totalement différent, mais votre méthode ici est beaucoup mieux que la mienne était, vous obtiendrez la réponse. Je vous remercie. – Kirk

0

Eh bien, cela semble être un hack complet, mais voici comment j'ai pu faire référence à la SqlDataSource.

ContentPlaceHolder cph = (ContentPlaceHolder)cell.Parent.Parent.Parent.Parent; 
SqlDataSource sds = (SqlDataSource)cph.FindControl("sqlReasonCodes"); 
DataView dv = (DataView)sds.Select(DataSourceSelectArguments.Empty); 

Il semble que depuis que je suis sur un MasterPage l'objet page normale n'existe pas comme prévu dans d'autres domaines.

Je suis ouvert à de meilleures idées que toute chose .Parent.Parent.Parent.Parent.