基于行数据的Datagrid条件行编辑

时间:2016-11-18 20:27:42

标签: c# asp.net

我有一个ASP.NET数据网格,里面有几行。我希望某些行可以编辑,但不是全部(基于该行中的特定数据项)。

最初,我使用ButtonColumn执行此操作,但我无法打开或关闭特定行。

这就是我现在所拥有的:

<asp:DataGrid ID="grid1" runat="server" AutoGenerateColumns="false" EnableViewState="true" CssClass="GridviewControlStyle" CellSpacing="0" CellPadding="4" HeaderStyle-CssClass="HeaderStyle"
    OnEditCommand="grid1_EditCommand" OnUpdateCommand="grid1_UpdateCommand" OnCancelCommand="grid1_CancelCommand" OnItemDataBound="grid1d_ItemDataBound">
    <Columns>
        <asp:TemplateColumn>
            <HeaderTemplate>
                <strong><%# Resources.Status %></strong>
            </HeaderTemplate>
            <ItemTemplate>
                <%# DataBinder.Eval(Container, "DataItem.STATUS") %>
            </ItemTemplate>
        </asp:TemplateColumn>
        <asp:TemplateColumn>
            <HeaderTemplate>
                <strong><%# Resources.Amount %></strong>
            </HeaderTemplate>
            <ItemTemplate>
                <%# DataBinder.Eval(Container, "DataItem.AMT") %>
            </ItemTemplate>
            <EditItemTemplate>
                <asp:CustomValidator ID="cvAmountGrid" OnServerValidate="cvAmountGrid_ServerValidate" Display="None" runat="server" ControlToValidate="txtAmount" />
                <asp:TextBox ID="txtAmount" runat="server" Text='<%# DataBinder.Eval(Container, "DataItem.AMT") %>' CssClass="small" />
            </EditItemTemplate>
        </asp:TemplateColumn>
        <asp:TemplateColumn>
            <ItemTemplate>
                <asp:Button runat="server" Text="Edit" ID="btnEdit" Visible='<%# IsRowEditable(Eval("STATUS").ToString()) %>' CommandName="Edit" />
                <asp:Button runat="server" Text="Update" ID="btnUpdate" Visible="false" CommandName="Update" />
                <asp:Button runat="server" Text="Cancel" ID="btnCancel" Visible="false" CommandName="Cancel" />
            </ItemTemplate>
        </asp:TemplateColumn>
</asp:DataGrid>

代码背后:

public bool IsRowEditable(string status)
{
    return !status.Equals("Locked", StringComparison.OrdinalIgnoreCase);
}

protected void grid1_EditCommand(object source, DataGridCommandEventArgs e)
{
    grid1.EditItemIndex = e.Item.ItemIndex;

    grid1.DataBind();

    TextBox t = e.Item.FindControl("txtAmount") as TextBox;

    t.Visible = true; //this can't be found

    Button b = e.Item.FindControl("btnEdit") as Button;

    b.Visible = false;

    Button u = e.Item.FindControl("btnUpdate") as Button;

    u.Visible = true;

    Button c = e.Item.FindControl("btnCancel") as Button;

    c.Visible = true;    
}

这种方法遇到了一些问题。首先,调用DataBind似乎重置了我在任何按钮上设置的可见性状态。如果我没有数据绑定,那么我的可编辑列不会显示为可编辑。所以,我尝试手动设置文本框可编辑;但是findcontrol返回null,所以我不能。我在这里做错了什么?

2 个答案:

答案 0 :(得分:1)

实现它的另一种方式;

  • 我删除了数据验证和列名数据绑定器以避免 复杂性。你可以在下面试试。
  • 更新和取消按钮位于EditItemTemplate下,因此它们将出现在编辑事件中。

<强> .ASPX

<asp:DataGrid ID="grid1" runat="server" AutoGenerateColumns="false" EnableViewState="true" CssClass="GridviewControlStyle" CellSpacing="0" CellPadding="4" HeaderStyle-CssClass="HeaderStyle"
OnEditCommand="grid1_EditCommand" OnUpdateCommand="grid1_UpdateCommand" OnCancelCommand="grid1_CancelCommand" OnItemDataBound="grid1d_ItemDataBound">
<Columns>
    <asp:TemplateColumn>
        <HeaderTemplate>
            <strong>Status</strong>
        </HeaderTemplate>
        <ItemTemplate>
            <%# DataBinder.Eval(Container, "DataItem.STATUS") %>
        </ItemTemplate>
    </asp:TemplateColumn>
    <asp:TemplateColumn>
        <HeaderTemplate>
            <strong>Amount</strong>
        </HeaderTemplate>
        <ItemTemplate>
            <%# DataBinder.Eval(Container, "DataItem.AMT") %>
        </ItemTemplate>
     <EditItemTemplate>
            <asp:TextBox ID="txtAmount" runat="server" Text='<%# DataBinder.Eval(Container, "DataItem.AMT") %>' CssClass="small" ReadOnly="false"/>
        </EditItemTemplate>
    </asp:TemplateColumn>


    <asp:TemplateColumn>
        <ItemTemplate>
            <asp:Button runat="server" Text="Edit" ID="btnEdit" Visible='<%# IsRowEditable(Eval("STATUS").ToString()) %>' CommandName="Edit" />
         </ItemTemplate>
        <EditItemTemplate>
            <asp:Button runat="server" Text="Update" ID="btnUpdate"  CommandName="Update" />
            <asp:Button runat="server" Text="Cancel" ID="btnCancel"  CommandName="Cancel" />
       </EditItemTemplate>
    </asp:TemplateColumn>
    </Columns>

代码背后

  • 您没有手动设置可见性。 EditItemTemplate将在编辑事件中处理它,当用户单击取消或更新时,编辑模板将替换为视图。
  • 我使用了一些硬编码的数据项列表,您可以将其替换为实际数据源并尝试。

        List<DataItem> t;
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            LoadData();
        }
    }
    
    private void LoadData()
    {
        t = new List<DataItem>();
        DataItem t1 = new DataItem() { AMT = 5, STATUS = "LOCKED" };
        DataItem t2 = new DataItem() { AMT = 15, STATUS = "OPEN" };
        DataItem t3 = new DataItem() { AMT = 25, STATUS = "OPEN" };
        DataItem t4 = new DataItem() { AMT = 35, STATUS = "LOCKED" };
        t.Add(t1);
        t.Add(t2);
        t.Add(t3);
        t.Add(t4);
        grid1.DataSource = t;
        grid1.DataBind();
    }
    
    
    
    protected void grid1_UpdateCommand(object sender, DataGridCommandEventArgs e)
    {
        string newAmount = (e.Item.Cells[1].FindControl("txtAmount") as TextBox).Text;
    
        //Update the data source with edited data
    
        grid1.EditItemIndex = -1;
    
        //Load Data with updated data
        LoadData();
    
    }
    
    protected void grid1_CancelCommand(object sender, DataGridCommandEventArgs e)
    {
        grid1.EditItemIndex = -1; //Bring back the previous state
        LoadData();
    }
    
    
    public bool IsRowEditable(string status)
    {
        return !status.Equals("Locked", StringComparison.OrdinalIgnoreCase);
    }
    
    protected void grid1_EditCommand(object source, DataGridCommandEventArgs e)
    {
        grid1.EditItemIndex = e.Item.ItemIndex;
        LoadData();
    }
    
    protected void grid1d_ItemDataBound(object sender, DataGridItemEventArgs e)
    {
    
    }
    

<强> DataItem.cs

public class DataItem
{
    public int AMT { get; set; }
    public string STATUS { get; set; }
}

答案 1 :(得分:0)

好的,我想出了一个更好的方法来做到这一点。我将以下代码添加到所有三个按钮的标记中:

Visible='<%# IsRowEditing(Container.ItemIndex) %>'

在我的代码后面,我检查了当前是否正在编辑该行,并使用它来控制按钮的可见性:

protected bool IsRowEditing(int index)
{
    return index > 0 && index == grid1.EditItemIndex;
}

这解决了我所有的问题,并且比我之前尝试做的要简单得多。数据绑定也适用于此方法。