【问题标题】:Binding and Updating LINQ object in Gridview在 Gridview 中绑定和更新 LINQ 对象
【发布时间】:2013-11-15 07:26:08
【问题描述】:

我整天都在困扰我的 Gridview 完全有问题。我不经常使用 Gridviews,所以其中一些让我感到困惑,而且 Google 并没有像我希望的那样提供帮助。

我正在尝试将通过 LINQ 创建的对象绑定到网格视图,然后进行一些更新。

XAML:

<asp:GridView runat="server" ID="GV1"
        onrowediting="gridViewUsers_RowEditing"
        onrowcancelingedit="gridViewUsers_RowCancelingEdit"
        onrowdeleting="gridViewUsers_RowDeleting"
        onrowupdating="gridViewUsers_RowUpdating"
        >
    <Columns>
        <asp:CommandField ShowEditButton="True" />
    </Columns>
</asp:GridView>

代码:

private void BindGrid()
{
    List<Room> stuff = new List<Room>();
    Hotel = dc1.Rooms.ToList();

    GV1.DataSource = Hotel;
    GV1.DataBind();
}

protected void gridViewUsers_RowEditing(object sender, GridViewEditEventArgs e)
{
    GV1.EditIndex = e.NewEditIndex;
    BindGrid();
}

我只想从选定的行中获取 Room 对象并通过 LINQ 将其更新回数据库。但我似乎无法接触到那个物体。我的下一个尝试是从行中获取每个条目。所以我找到了类似下面示例的代码。但一切都是空的。

    protected void gridViewUsers_RowUpdating(object sender, GridViewUpdateEventArgs e)
    {
        string tenant = ((TextBox)(GV1.Rows[e.RowIndex].FindControl("Tenant"))).Text;
        string age = ((TextBox)(GV1.Rows[e.RowIndex].FindControl("Age"))).Text;
        string roomno = ((TextBox)(GV1.Rows[e.RowIndex].FindControl("Room_No"))).Text;            
        BindGrid();
    }

【问题讨论】:

  • 我认为这只是一个错字,但是您的 gridview ID 是 GV1 而在更新事件时它是 gridViewUsers_RowUpdating 所以您确定您正在访问正确的网格视图吗??
  • 这是一个错字。方法名称取自我找到的另一个 GridView。它指向正确的方法,我正在追踪该方法。
  • 如果您没有明确定义列,那么正如Yevgeniy.Chernobrivets 发布的那样定义您的列,然后您可以使用Textbox txtbxtenant = (TextBox)row.FindControl("Tenant"); 轻松访问您的控件
  • 我确实更改了 gridview 以明确定义列。很抱歉我不能给你这个例子,因为我现在在工作并且远离代码。但是文本框 txtbxtenant = (TextBox)row.FindControl("Tenant");我上次尝试时仍然拉回 null。
  • 到目前为止我最接近的是 ((TextBox)GV1.Rows[e.RowIndex].Cells[1].Controls[0]).Text 拉回原始值。我找不到编辑后的值。 GV1.Rows[e.RowIndex].Cells[1].Controls.Count 为 1,因此单元格中没有任何其他控件。

标签: c# asp.net linq gridview


【解决方案1】:

尝试设置 AutoGenerateColumns = false 并手动提供列。 比如:

<asp:GridView runat="server" ID="GV1"
    onrowediting="gridViewUsers_RowEditing"
    onrowcancelingedit="gridViewUsers_RowCancelingEdit"
    onrowdeleting="gridViewUsers_RowDeleting"
    onrowupdating="gridViewUsers_RowUpdating"
    AutoGenerateColumns = "false"
    >
    <Columns>
        <asp:CommandField ShowEditButton="True" />
        <asp:BoundField HeaderText="Tenant" DataField="Tenant" />
        <asp:BoundField HeaderText="Age" DataField="Age" />
        <asp:BoundField HeaderText="Room_No" DataField="Room_No" />
    </Columns>
</asp:GridView>

编辑: 请将此代码添加到您的解决方案中

public static int GetCellIndexByFieldHandle(this GridView grid, string fieldHandle)
{
    int iCellIndex = -1;

    for (int iColIndex = 0; iColIndex < grid.Columns.Count; iColIndex++)
    {
        if (grid.Columns[iColIndex] is DataControlField)
        {
            DataControlField col = (DataControlField)grid.Columns[iColIndex];
            if ((col is BoundField && string.Compare(((BoundField)col).DataField, fieldHandle, true) == 0)
                || string.Compare(col.SortExpression, fieldHandle, true) == 0
                || col.HeaderText.Contains(fieldHandle))
            {
                iCellIndex = iColIndex;
                break;
            }
        }
    }
    return iCellIndex;
}

/// <summary>
/// Gets the ordinal index of a TableCell in a rendered GridViewRow, using a text fieldHandle (e.g. the corresponding column's DataFieldName/SortExpression/HeaderText)
/// </summary>
public static int GetCellIndexByFieldHandle(this GridViewRow row, string fieldHandle)
{
    return GetCellIndexByFieldHandle((GridView)row.Parent.Parent, fieldHandle);
}

然后试试

string tenant = ((TextBox)GV1.Rows[e.RowIndex].Cells[GV1.Rows[e.RowIndex].GetCellIndexByFieldHandle("Tenant")].Controls[0]).Text;

【讨论】:

  • 我这样做了,但当我尝试 .FindControl() 时仍然为空。
  • 没有办法只抓取选中的房间吗?
  • 嗯,有一个错误,因为两个扩展方法都没有只有一个参数。所以我将调用更改为 .GetCellIndexByFieldHandle(GV1.Rows[e.RowIndex], "Tenant")] 但是,我收到错误消息“必须在非泛型静态类中定义扩展方法”。必须有一种更简单的方法来做到这一点。
  • 是的,应该将扩展方法移动到某个静态类。
  • 我猜如果您是通过标记静态创建列,您可以使用单元格索引器来查找正确的单元格。以单元格[1] 为例。
【解决方案2】:

尝试使用此代码访问您的 textbox 值。

 protected void gridViewUsers_RowUpdating(object sender, GridViewUpdateEventArgs e)
    {
         GridViewRow row = gridViewUsers.Rows[e.RowIndex];
        Textbox txtbxtenant = (TextBox)row.FindControl("Tenant");
         string tenanat = Convert.toString(tentant.text);
        Textbox txtbxAge =(Textbox)row.FindControl("Age");                   
        string age = Convert.toString(Age.text);
       // string roomno = ((TextBox)  
       //(GV1.Rows[e.RowIndex].FindControl("Room_No"))).Text;            
       // BindGrid();

    }

【讨论】:

  • 租户和年龄为空。因此,tenanat 和 age 抛出“对象引用未设置为对象的实例。”
  • @Jeremy 请检查更新后的答案,如果这不起作用,请告诉我。
  • (TextBox)row.FindControl("Tenant");不管你把它放在什么文本框里,它仍然返回 null。:(
  • @Jeremy 这不是关于重命名textbox 我提到Convert.Tostring 我在将文本框值分配给字符串时添加的。但是,您能发布您的 gridview 代码吗?
  • 我很困惑。文本框 txtbxtenant = (TextBox)row.FindControl("租户");字符串tenanat = Convert.toString(tentant.text);所以您正在将当前正在创建的字符串转换为字符串?那会坏掉的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多