Основные GridView в поддержке с объекта DataTable


Мне нужно добавить список имен и (опционально) ссылки на мои страницы ASP.net .

Я научилась (надеюсь) использовать GridView для этого, в основном работают из примера, приведенного в этом блоге запись: добавление динамического ряда-в-сетке.

Я добавил GridView на моем сайте:

<asp:GridView
        id="NameLinksGridView" runat="server"
        AutoGenerateColumns="false" ShowFooter="true">
    <Columns>
        <asp:TemplateField HeaderText="Name">
            <ItemTemplate>
                <asp:TextBox ID="Name" runat="server" />
            </ItemTemplate>
        </asp:TemplateField> 
        <asp:TemplateField HeaderText="Link">
            <ItemTemplate>
                <asp:TextBox ID="Link" runat="server" />
            </ItemTemplate>
            <FooterStyle HorizontalAlign="Right" />
            <FooterTemplate>
                <asp:Button 
                    ID="addNameLink" runat="server"
                    Text="Add" onclick="addNameLink_Click"
                    CausesValidation="false" />
            </FooterTemplate> 
        </asp:TemplateField>
    </Columns>
</asp:GridView>

С кодом:

private void setupInitialNameLinks()
{
    DataTable dt = getNameLinksTable();
    /* store DataTable in the ViewState for preservation across PostBack's */
    ViewState["CurrentTable"] = dt;
    /* bind the displayed DataGrid to our DataTable */
    NameLinksGridView.DataSource = dt;
    NameLinksGridView.DataBind();
    /* set current TextBox values to the values in the DataTable 
        * surely the DataBind should do this for us?!? */
    setTextBoxValuesToDataTableValues(dt);
}

private DataTable getNameLinksTable()
{
    DataTable dt = new DataTable();
    dt.Columns.Add(new DataColumn("Name", typeof(string)));
    dt.Columns.Add(new DataColumn("Link", typeof(string)));

    var existingNameLinks = getExistingNameLinks();
    if (existingNameLinks.Count() > 0)
    {
        foreach (var auth in existing)
        {
            DataRow r = dt.NewRow();
            r["Name"] = auth.name;
            r["Link"] = auth.link;
            dt.Rows.Add(r);
        }
    }
    else
    {
        DataRow emptyRow = getNameLinksEmptyRow(dt);
        dt.Rows.Add(emptyRow);
    }
    return dt;
}

private static DataRow getNameLinksEmptyRow(DataTable dt)
{
    DataRow emptyRow = dt.NewRow();
    emptyRow["Name"] = String.Empty;
    emptyRow["Link"] = String.Empty;
    return emptyRow;
}

protected void addNameLink_Click(object sender, EventArgs e)
{
    if (ViewState["CurrentTable"] != null)
    {
        DataTable dt = (DataTable) ViewState["CurrentTable"];
        DataRow dr = getNameLinksEmptyRow(dt);
        dt.Rows.Add(dr);

        /* update our DataTable to the POST'ed data */
        int numPostedRows = dt.Rows.Count - 1;
        for (int i = 0; i < numPostedRows; i++)
        {
            TextBox tbName = 
                (TextBox)NameLinksGridView.Rows[i].Cells[0].FindControl("Name");
            string name = tbName.Text; // get POST'ed value
            dt.Rows[i]["Name"] = name; // set DataTable val to the POST'ed value
            TextBox tbLink = 
                (TextBox)NameLinksGridView.Rows[i].Cells[1].FindControl("Link");
            string link = tbLink.Text;
            dt.Rows[i]["Link"] = link;
        }

        /* store our DataTable in the ViewState for preservation across PostBack */
        ViewState["CurrentTable"] = dt;

        /* bind the displayed DataGrid to our DataTable */
        NameLinksGridView.DataSource = dt;
        NameLinksGridView.DataBind();

        /* set current TextBox values to the values in the DataTable
            * needs to happen after the DataBind()
            * surely the DataBind should do this for us?!? */
        setTextBoxValuesToDataTableValues(dt);

    }
    else
    {
        throw new Exception("CurrentTable is null!");
    }
}

private void setTextBoxValuesToDataTableValues(DataTable dt)
{
    for (int i = 0; i < dt.Rows.Count; i++)
    {
        TextBox tbName = (TextBox)NameLinksGridView.Rows[i].Cells[0].FindControl("Name");
        tbName.Text = dt.Rows[i]["Name"].ToString();
        TextBox tbLink = (TextBox)NameLinksGridView.Rows[i].Cells[1].FindControl("Link");
        tbLink.Text = dt.Rows[i]["Link"].ToString();
    }
}

Это код выглядеть хлопотно, подвержено ошибкам, umnaintanable, не правильный способ сделать это, и т. д.?

Одна большая небольшая путаница у меня (хотя код работает) — зачем нужно хранить экземпляр DataTable в состояние отображения вручную и мое текстовое поле отображаемых значений вручную (в setTextBoxValuesToDataTableValues)? Конечно, в GridView государства должен быть сохранен через пост без меня необходимости беспокоиться о ViewState и на привязку должен автоматически установить значения текстового поля?



5116
2
задан 11 декабря 2011 в 11:12 Источник Поделиться
Комментарии
1 ответ

Что касается того, чтобы получить/установить значение поля, вы должны узнать связывать выражение. Например, вы могли бы иметь:

<asp:TextBox ID="Name" runat="server" Text='<%# Bind("Name") %>' /> 

Для одного "правильного" способа делать вещи, взгляните на это прохождение массовое редактирование строк в элемент управления GridView.

2
ответ дан 13 декабря 2011 в 12:12 Источник Поделиться