aspnet 和 C#:如何将 TemplateField 链接到动态创建的匿名类型?

发布于 2024-10-29 14:06:54 字数 2389 浏览 0 评论 0原文

我有一个返回匿名类型的 Linq 查询,然后将其用作 GridView 的数据源。其中只有 1 列需要可编辑。我只想能够单击编辑按钮并使该 1 列的所有行都成为文本框(理想情况下)。我会满足于每行都有一个 CommandField。问题是,我不知道如何在不创建自定义类或手动处理所有字段的情况下做到这一点。此列还必须以特定方式更新数据库中的值(因此我需要为该查询编写自定义代码)。

目前,我可以轻松地将整个内容显示在网格视图中。我什至创建了一个自定义数据表来用作数据源,并且效果很好。但我仍然不知道如何添加编辑功能。我找到的教程要么针对 DataSource 控件,要么涉及创建扩展 GridView 等的自定义类。我在 aspx 页面中添加了一个 CommandField,它工作正常,但 DataTable 中的 ReadOnly 列仍然可编辑。

我宁愿有一个简单的解决方案...例如,在 .aspx 页面中创建一个 TemplateField,我可以提供一个 Item 和 EditItem 模板,并以某种方式绑定到我的 Linq 查询返回的字段。

我在下面添加了一些伪代码,它创建了 2 个 GridView。仅显示所有信息,但不可编辑。另一个使用 DataTable,其中显示 ColA、来自带有空行的 aspx 页面的 ColB 以及来自代码隐藏页面的 ColB(已填充)。

将查询绑定到GridView:

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

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

制作DataTable

    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();

在aspx页面中制作GridView控件

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

I have a Linq query that returns an anonymous type, which I then use as the data source for a GridView. Only 1 of those columns need to be editable. I just want to be able to click on an edit button and have ALL the rows of that 1 column become textboxes (ideally). I will settle for having a CommandField for each row. The problem is, I don't know how to do that without creating a custom class or manually dealing with all the fields. This column must also update a value in the database in a specific way (so I need to write custom code for that query).

At the moment, I'm easily able to make the whole thing display in the Grid View. I even created a custom DataTable to use as the Data Source and that works okay. But I'm still at a loss as to how to add the editing capabilities. The tutorials I have found are either for a DataSource control or involve making custom classes that extend GridView and what not. I've added a CommandField in the aspx page, which works okay but the ReadOnly columns in the DataTable are still editable.

I'd rather have a simple solution...for example, making a TemplateField in the .aspx page that I can give an Item and EditItem Template and somehow bind to the fields returned by my Linq query.

I've included some pseudocode below which creates 2 GridViews. One just has all the information displayed, but not editable. The other uses the DataTable which shows ColA, the ColB from the aspx page with empty rows and the ColB from the code behind page, populated.

Binding Query to GridView:

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

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

Making DataTable

    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();

Making GridView Control in aspx Page

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

就是爱搞怪 2024-11-05 14:06:55

为了避免该错误,您必须处理所有行事件;像这样的东西

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

To avoid the error, you'll have to handle all of the row events; something like this

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

and

    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
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文