aspnet и C #: как связать TemplateField с динамически созданным анонимным типом? - PullRequest
1 голос
/ 04 апреля 2011

У меня есть запрос Linq, который возвращает анонимный тип, который я затем использую в качестве источника данных для GridView. Только 1 из этих столбцов должны быть доступны для редактирования. Я просто хочу иметь возможность нажать на кнопку редактирования и сделать ВСЕ строки этого 1 столбца текстовыми полями (в идеале). Я согласен на наличие CommandField для каждой строки. Проблема в том, что я не знаю, как это сделать, не создавая пользовательский класс или не обрабатывая вручную все поля. Этот столбец также должен обновлять значение в базе данных особым образом (поэтому мне нужно написать собственный код для этого запроса).

В настоящее время я легко могу отобразить все это в виде сетки. Я даже создал собственный DataTable для использования в качестве источника данных, и это работает нормально. Но я все еще в растерянности относительно того, как добавить возможности редактирования . Обучающие программы, которые я нашел, предназначены либо для элемента управления DataSource, либо включают создание пользовательских классов, расширяющих GridView, а что нет. Я добавил CommandField на странице aspx, которая работает нормально, но столбцы ReadOnly в DataTable по-прежнему доступны для редактирования.

Я бы предпочел простое решение ... например, сделать TemplateField на странице .aspx, чтобы я мог предоставить Item и EditItem Template и каким-то образом связать поля, возвращаемые моим запросом Linq.

Ниже я включил псевдокод, который создает 2 GridView. Один просто отображает всю информацию, но не редактируется. Другой использует DataTable, который показывает ColA, ColB из страницы aspx с пустыми строками и ColB из кода позади страницы.

Привязка запроса к GridView:

var qry = from t in database
          ...
          select new { colA, colB };

GridView2.DataSource = qry; // not shown in pseudocode
GridView2.DataBind();

Создание таблицы данных

    const string ColA = "ColA";
    const string ColB = "ColB";

    DataTable dt = new DataTable();
    DataColumn dc = new DataColumn(ColA, typeof(System.String));
    dt.Columns.Add(dc);

    dc = new DataColumn(ColB, typeof(System.String));
    dt.Columns.Add(dc);

    foreach (var item in qry) {
        DataRow dr = dt.NewRow();
        dr[ColA] = item.ColA;
        dt.Rows.Add(dr);
    }

    foreach (DataColumn col in dt.Columns) {
        col.ReadOnly = false;
        BoundField bf = new BoundField();
        bf.DataField = col.ColumnName;
        bf.HeaderText = col.ColumnName;
        GridView1.Columns.Add(bf);
    }

    GridView1.DataSource = dt;
    GridView1.DataBind();

Создание элемента управления GridView на странице aspx

<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" >
  <Columns>
     <asp:TemplateField HeaderText="ColB">
       <EditItemTemplate>
          <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
       </EditItemTemplate>
       <ItemTemplate>
          <asp:Label ID="Label1" runat="server" ></asp:Label>
       </ItemTemplate>
     </asp:TemplateField>
     <asp:CommandField ButtonType="Button" ShowDeleteButton="True" 
        ShowEditButton="True" ShowInsertButton="True" UpdateText="Save">
     </asp:CommandField>
   </Columns>
</asp:GridView>

1 Ответ

1 голос
/ 04 апреля 2011

Чтобы избежать ошибки, вам придется обрабатывать все события строки;как то так

    <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" OnRowCancelingEdit="GridView1_RowCancelingEdit"
        OnRowCommand="GridView1_RowCommand" OnRowEditing="GridView1_RowEditing" OnRowUpdated="GridView1_RowUpdated">
        <Columns>
            <asp:BoundField DataField="ColA" ReadOnly="true" />
            <asp:TemplateField HeaderText="ColB">
                <EditItemTemplate>
                    <asp:TextBox ID="TextBox1" runat="server" Text='<%# Bind("ColB") %>'></asp:TextBox>
                </EditItemTemplate>
                <ItemTemplate>
                    <asp:Label ID="Label1" runat="server" Text='<%# Bind("ColB") %>'></asp:Label>
                </ItemTemplate>
            </asp:TemplateField>
            <asp:CommandField ButtonType="Button" ShowDeleteButton="True" ShowEditButton="True"
                ShowInsertButton="True" UpdateText="Save"></asp:CommandField>
        </Columns>
    </asp:GridView>

и

    protected void GridView1_RowEditing(object sender, GridViewEditEventArgs e)
    {
        GridView1.EditIndex = e.NewEditIndex;
    }

    protected void GridView1_RowUpdated(object sender, GridViewUpdatedEventArgs e)
    {
        // handle row updated
    }

    protected void GridView1_RowCancelingEdit(object sender, GridViewCancelEditEventArgs e)
    {
        GridView1.EditIndex = -1;
    }

    protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
    {
        // handle row command
    }
...