【问题标题】:Datagrid conditional row editing based on row data基于行数据的Datagrid条件行编辑
【发布时间】:2016-11-18 20:27:42
【问题描述】:

我有一个 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 所以我不能。我在这里做错了什么?

【问题讨论】:

    标签: c# asp.net


    【解决方案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; }
    }
    

    【讨论】:

      【解决方案2】:

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

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

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

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-04-25
        • 1970-01-01
        • 2011-08-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多