1

編集可能なスケジュールを表示するためDataControlFieldにで使用されるカスタムを作成しました。DetailsViewこれらの各カスタムフィールドには、ユーザーが選択できる値を入力するために使用されるDataSourceID文字列が渡されます。

DetailsViewが編集モードの場合、を表示しDropDownListて、ユーザーがからのアイテムのリストから選択できるようにしますSqlDataSource読み取り専用モードでは、選択した値のフルネームが表示されます。

読み取り専用モードでの問題は、渡されたSqlDataSourceのIDだけであり、それを実際のSqlDataSourceオブジェクトに変換しようとすると、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を編集モードにすると、うまく機能します。失敗するのはReadOnlyモードで、DataFieldプロパティに「PTO」の「P」、「Working」の「W」、「RequestedDayOff」の「R」などの値が渡されます。

私の問題は、DataFieldを対応する長い名前に変換することです。現在、私はこのコードを使用してSqlDataSourceを取得しています。

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

ここでは、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
}
4

2 に答える 2

3

.parent.parent...の代わりに次を使用します。

ContentPlaceHolder cph = (ContentPlaceHolder)this.Page.Master.FindControl("ContentPlaceHolderID");
于 2012-10-23T18:18:13.210 に答える
0

うーん、これは完全なハックのように思えますが、これが私が参照できた方法です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ます。

于 2012-08-09T17:44:08.573 に答える