Пользовательский DataControlField не сохраняет значение после обратной передачи

У меня проблема. Я создал пару кастомов DataControlFields потому что мне нужно отобразить данные, которые не приходят из DataSource на DataGrid,

Мне удалось получить контроль GridView но я не могу решить пару вопросов.

Мои элементы управления не сохраняют свои значения между постбэками. У меня есть разметка, сидящая внутри UpdatePanel который я поставил Conditional, Затем я настроил свои триггеры, исключая те из GridView, Я также попытался установить UpdateMode в Always, Я получаю такое же поведение здесь.

Вот моя разметка:

    <asp:UpdatePanel UpdateMode="Conditional" ID="reportchooserUpdatePanel" runat="server">
        <ContentTemplate>
            <Triggers>
                <asp:PostBackTrigger ControlID="ddlMonth" EventName="Load"  />
                <asp:PostBackTrigger ControlID="ddlMonth" EventName="SelectedIndexChanged"  />
                <asp:PostBackTrigger ControlID="ddlYear" EventName="DataBinding"  />
                <asp:PostBackTrigger ControlID="ddlYear" EventName="SelectedIndexChanged
                <asp:PostBackTrigger ControlID="GenerateReportsButton" EventName="Click"  />                
            </Triggers>
            <table class="ms-formtable">
                <tr>
                    <td class="ms-formlabel">
                        <asp:Label ID="MonthYearLabel" runat="server" Text=""></asp:Label>
                    </td>
                    <td class="ms-formbody align-right">
                        <asp:DropDownList OnSelectedIndexChanged="ddlMonth_SelectedIndexChanged" AutoPostBack="true" runat="server" ID="ddlMonth" OnLoad="ddlMonth_Load">
                            <asp:ListItem Value="1">Januar</asp:ListItem>
                            <asp:ListItem Value="2">Februar</asp:ListItem>
                            <asp:ListItem Value="3">März</asp:ListItem>
                            <asp:ListItem Value="4">April</asp:ListItem>
                            <asp:ListItem Value="5">Mai</asp:ListItem>
                            <asp:ListItem Value="6">Juni</asp:ListItem>
                            <asp:ListItem Value="7">Juli</asp:ListItem>
                            <asp:ListItem Value="8">August</asp:ListItem>
                            <asp:ListItem Value="9">September</asp:ListItem>
                            <asp:ListItem Value="10">Oktober</asp:ListItem>
                            <asp:ListItem Value="11">November</asp:ListItem>
                            <asp:ListItem Value="12">Dezember</asp:ListItem>
                        </asp:DropDownList>                        
                    </td>
                    <td class="ms-formbody align-right">
                        <asp:DropDownList OnSelectedIndexChanged="ddlYear_SelectedIndexChanged" AutoPostBack="true" OnDataBinding="ddlYear_DataBinding" ID="ddlYear" runat="server"></asp:DropDownList>
                    </td>
                </tr>
                <tr>
                    <td style="width:100%;" class="ms-formbody" colspan="3">
                        <asp:GridView AutoGenerateColumns="false" ShowHeaderWhenEmpty="true" CssClass="grid-view" Width="100%" ID="gvProjects" runat="server">
                        </asp:GridView>
                    </td>
                    <td></td>
                    <td></td>
                </tr>
                <tr>
                    <td class="ms-formtoolbar align-right" colspan="3">
                        <asp:HyperLink Target="_blank" Font-Size="X-Small" ID="hlGembox" NavigateUrl="http://www.gemboxsoftware.com/spreadsheet/free-version" runat="server"></asp:HyperLink>
                        <asp:Button OnClientClick="AddNotification('Please wait...')" ID="GenerateReportsButton" runat="server" Text="" OnClick="GenerateReportsButton_Click" />
                    </td> 
                    <td></td>
                    <td></td>                   
                </tr>
            </table>
        </ContentTemplate>
    </asp:UpdatePanel>

А вот код одного из моих кастомов DataControlFields, Они в основном такие же, за исключением элементов управления, которые они отображают:

class TemplateDropDownControl : DataControlField
{
    SPList reportslist = ListItemHelper.GetReportsList();

    protected void InitializeDataCell(DataControlFieldCell cell, DataControlRowState rowState)
    {
        string ID = Guid.NewGuid().ToString();
        DropDownList list = new DropDownList();

        list.ID = ID;
        FillContentTypeDropDown(list);
        cell.Controls.Add(list);           
    }

    public override void InitializeCell(DataControlFieldCell cell, DataControlCellType cellType, DataControlRowState rowState, int rowIndex)
    {
        //Call the base method.
        base.InitializeCell(cell, cellType, rowState, rowIndex);

        this.InitializeDataCell(cell, rowState);
    }

    protected override DataControlField CreateField()
    {
        return new BoundField();
    }

    public string DataField
    {
        get
        {
            object value = base.ViewState["DataField"];
            if (value != null)
            {
                return value.ToString();
            }
            else
            {
                return string.Empty;
            }
        }
        set
        {
            base.ViewState["DataField"] = value;
            this.OnFieldChanged();
        }
    }

    public override void ExtractValuesFromCell(System.Collections.Specialized.IOrderedDictionary dictionary, DataControlFieldCell cell, DataControlRowState rowState, bool includeReadOnly)
    {
        DropDownList list = cell.Controls[0] as DropDownList;

        ListItem selectedValue = list.SelectedItem;

        if (dictionary.Contains(DataField))
            dictionary[DataField] = selectedValue.Value;
        else
            dictionary.Add(DataField, selectedValue.Value);
    }

    private void FillContentTypeDropDown(DropDownList ddlContentTypes)
    {
        if (reportslist == null)
            return;

        SPContentTypeCollection cts = reportslist.ContentTypes;

        ddlContentTypes.Items.Clear();

        foreach (SPContentType ct in cts)
        {
            ddlContentTypes.Items.Add(new ListItem() { Text = ct.Name, Value = ct.DocumentTemplateUrl + ct.DocumentTemplate.Replace("~site", "") });
        }
    }
}

И, наконец, вот код, где я добавляю их на свою страницу. Я установил AutoGenerateColumns собственность GridView ложно в разметке:

    private void BindDataGrid()
    {
        DataTable table = new DataTable();
        table = new DataTable();
        table.Columns.Add(ResourceHelper.LoadResource(ResourceName.ProjectnumberTableString));
        table.Columns.Add(ResourceHelper.LoadResource(ResourceName.TemplateString));
        table.Columns.Add(ResourceHelper.LoadResource(ResourceName.FileFormatString));

        gvProjects.Columns.Clear();
        gvProjects.DataSource = null;

        //Fill DataTable here...

        BoundField projectnumberField = new BoundField();
        projectnumberField.HeaderText = ResourceHelper.LoadResource(ResourceName.ProjectnumberTableString);
        projectnumberField.DataField = ResourceHelper.LoadResource(ResourceName.ProjectnumberTableString);

        FileFormatCheckboxControl checkBoxControl = new FileFormatCheckboxControl();
        checkBoxControl.DataField = ResourceHelper.LoadResource(ResourceName.FileFormatString);
        checkBoxControl.HeaderText = ResourceHelper.LoadResource(ResourceName.FileFormatString);

        TemplateDropDownControl dropDownControl = new TemplateDropDownControl();
        dropDownControl.DataField = ResourceHelper.LoadResource(ResourceName.TemplateString);
        dropDownControl.HeaderText = ResourceHelper.LoadResource(ResourceName.TemplateString);

        gvProjects.Columns.Add(projectnumberField);
        gvProjects.Columns.Add(dropDownControl);
        gvProjects.Columns.Add(checkBoxControl);  

        gvProjects.DataSource = table;
        gvProjects.DataBind();
    } 

Кто-нибудь знает, что я здесь делаю не так?

РЕДАКТИРОВАТЬ: Может быть, я должен упомянуть, что я отображаю форму в модальном диалоговом окне Sharepoint.

1 ответ

Решение

Хорошо, я решил это по-другому, так как я понятия не имел, почему моя проблема продолжала происходить. Я просто использую asp:Table сейчас и генерировать все это из кода. У меня есть один метод для этого, который я вызываю на каждой странице обратной передачи. Важно отметить, что вызывать этот метод только из Page_Load, Это не сработало, когда я позвонил Page_Init,

Вот мой код:

    private void BindDataGrid()
    {
        GenerateReportsButton.Enabled = true;
        reportsTable.Rows.Clear();

        TableHeaderRow headerrow = new TableHeaderRow();
        TableHeaderCell pnumberheader = new TableHeaderCell();
        TableHeaderCell templateheader = new TableHeaderCell();
        TableHeaderCell fileFormatHeader = new TableHeaderCell();

        pnumberheader.Text = ResourceHelper.LoadResource(ResourceName.ProjectnumberTableString);
        templateheader.Text = ResourceHelper.LoadResource(ResourceName.TemplateString);
        fileFormatHeader.Text = ResourceHelper.LoadResource(ResourceName.FileFormatString);

        headerrow.Cells.Add(pnumberheader);
        headerrow.Cells.Add(templateheader);
        headerrow.Cells.Add(fileFormatHeader);
        reportsTable.Rows.Add(headerrow);

        if (ddlYear.SelectedItem == null || ddlMonth.SelectedItem == null)
        {
            int index = reportsTable.Rows.Add(new TableRow());
            TableCell cell = new TableCell();
            cell.ColumnSpan = 3;
            cell.Text = ResourceHelper.LoadResource(ResourceName.NoListItemsForMonthYear);
            reportsTable.Rows[index].Cells.Add(cell);
            GenerateReportsButton.Enabled = false;
            return;
        }

        //Get items here

        if (items.Count == 0)
        {
            int index = reportsTable.Rows.Add(new TableRow());
            TableCell cell = new TableCell();
            cell.ColumnSpan = 3;
            cell.Text = ResourceHelper.LoadResource(ResourceName.NoListItemsForMonthYear);
            reportsTable.Rows[index].Cells.Add(cell);
            GenerateReportsButton.Enabled = false;
            return;
        }
        else
            InsertRowIntoProjectTable("Intern", "Intern");

        List<string> processedReports = new List<string>();

        foreach(SPListItem item in items)
        {
            if (item[Variables.projectNumberField].ToString() != "Intern" && !processedReports.Contains(item[Variables.activityProject].ToString()))
            {
                InsertRowIntoProjectTable(item[Variables.activityProject].ToString(), item.ID.ToString());
                processedReports.Add(item[Variables.activityProject].ToString());
            }
        }
    }

Тогда вы можете просто прочитать данные так:

foreach(TableRow row in reportsTable.Rows)
{
    //Important since foreach also iterates over headerrow
    if (row.Cells[1].Controls.Count > 0 && row.Cells[1].Controls[0] is DropDownList)
    {
         string value1= row.Cells[0].Text;
         string value2= ((DropDownList)row.Cells[1].Controls[0]).SelectedValue;

         //do stuff with the data
    }
 }

Если кто-то все еще находит ответ на мою конкретную проблему выше, не стесняйтесь добавлять его. Я отмечу это как принятый, как только проверено, что это работает.

Другие вопросы по тегам