Gridview 中的必填字段验证器取决于条件 c#

Required Field Validator in Gridview depend on condition c#

我在 Gridview 中有一个必填字段验证器。我只想在 ddlPartsStatus 为 "Ordered" 时触发验证器。我就是无法让它工作。

目前所有文本框都触发必填字段验证器。

我的代码

<asp:GridView ID="gvPartsToOrderDetail" CssClass="gvPartsToOrderDetail" runat="server" AutoGenerateColumns="false" OnRowDataBound="gvPartsToOrderDetail_RowDataBound">
    <Columns>
        <asp:TemplateField HeaderText="Ticket Number">
            <ItemTemplate>
                <asp:TextBox ID="txtTicketNo" Text='<%# Eval("TicketNo") %>' runat="server"></asp:TextBox>
                <asp:RequiredFieldValidator ID="rfvTxtTicketNo" runat="server" ForeColor="Red" Font-Bold="true" Font-Size="Medium" ErrorMessage="*" ControlToValidate="txtTicketNo" ValidationGroup="Submit"></asp:RequiredFieldValidator>
            </ItemTemplate>
        </asp:TemplateField>
        <asp:TemplateField HeaderText="Parts Status">
            <ItemTemplate>
                <asp:DropDownList ID="ddlPartStatus" runat="server" AutoPostBack="true">
                    <asp:ListItem Value="0" Text="-Select-"></asp:ListItem>
                    <asp:ListItem Value="1" Text="Ordered"></asp:ListItem>
                </asp:DropDownList>
            </ItemTemplate>
        </asp:TemplateField>
    </Columns>
</asp:GridView>

<asp:Button ID="btnSubmit" CssClass="btnSubmit" runat="server" Text="Submit" ValidationGroup="Submit" OnClick="btnSubmit_Click" />

非常感谢任何帮助。谢谢

为此你需要 CustomValidator。然后 ClientValidationFunction 应该评估 TextBox 和 DropDownList。

<asp:CustomValidator ID="CustomValidator1" runat="server" ErrorMessage="*" 
    ValidationGroup="Submit" ControlToValidate="txtTicketNo" 
    ClientValidationFunction="checkValuesInRow" ValidateEmptyText="true"></asp:CustomValidator>

<script type="text/javascript">
    function checkValuesInRow(sender, element) {
        var isValid = false;
        var ddlValue = $("#" + sender.controltovalidate).closest('tr').find('select').val();
        if (element.Value === "" && ddlValue === "0") {
            isValid = true;
        }
        element.IsValid = isValid;
    }
</script>

NOTE: Further reading is intended to be informative and not practical given all the clicking that must happen. But it shows how things can be done, not necessarily how the should be done and is only here due to the OP's Request for more info...so, here we go

鉴于此 GridView <ItemTemplate>:

    <asp:TextBox ID="tbxTicketNo" runat="server" Text='<%# Bind("TicketNo") %>'></asp:TextBox>
    <asp:RequiredFieldValidator ID="rfvTxtTicketNo" runat="server" 
        ErrorMessage="RequiredFieldValidator" Text="*"
        ControlToValidate="tbxTicketNo"
        InitialValue="0"
        ValidationGroup="vgSubmit">
    </asp:RequiredFieldValidator>

根据您的行数,使用 x 个验证器呈现 table。您可以使用浏览器的开发人员工具检查 gvPartsToOrderDetail,您会在其中找到与此类似的内容,请注意所有行上的 data-val-validationgroup 属性:

    <span 
      data-val-controltovalidate="ContentPlaceHolder1_gvPartsToOrderDetail_tbxTicketNo_0" 
      data-val-errormessage="RequiredFieldValidator" 
      data-val-validationgroup="vgSubmit"
      id="ContentPlaceHolder1_gvPartsToOrderDetail_rfvTxtTicketNo_0" 
      data-val="true" 
      data-val-evaluationfunction="RequiredFieldValidatorEvaluateIsValid" 
      data-val-initialvalue="0" style="visibility:hidden;">*</span>

你看到 data-val-validationgroup="vgSubmit" 不是唯一的了吗? 因此,当您单击 btnSubmit 并将其 ValidationGroup 设置为“vgSubmit”时,它们都会被触发。

现在给出@VDWWD 的回答,您可能更愿意保持这种方式。这完全没问题且合法,可能更符合您的需求。

但是要解决验证组的 non-uniqueness,您可以在标记中执行此操作:

    <asp:RequiredFieldValidator ID="rfvTxtTicketNo" runat="server" 
        ...
        ValidationGroup='<%# string.Format("Submit_{0}", Container.DataItemIndex) %>'>
    </asp:RequiredFieldValidator>

然后将呈现:

<span ... data-val-validationgroup="Submit_0" ... </span>
<span ... data-val-validationgroup="Submit_1" ... </span>
<span ... data-val-validationgroup="Submit_2" ... </span>

但是现在你遇到了设计问题。要在 gridview 中隔离验证组并将其绑定到您的提交按钮,您需要 select 一行,这意味着引入一个 Select 命令按钮。更多的点击,不好,但可以做到。但这会引入更多问题:

1. How do you tell the Submit button which validation group to validate?
2. Also the Submit button has a nasty habit of Posting back regardless of validation.

两者都可以这样修复:

    <asp:Button ID="btnSubmit" runat="server" Text="Button" 
        OnClientClick="return Page_ClientValidate('vgSubmit_1')" />

它是在 btnSubmit_PreRender 中以编程方式生成的,如下所示:

    protected void btnSubmit_PreRender( object sender, EventArgs e )
    {
        btnSubmit.OnClientClick = string.Format( "return Page_ClientValidate('vgSubmit_{0}')", gvPartsToOrderDetail.SelectedIndex );
    }

下面是代码隐藏和页面标记以供审查:

To sum up, this solution, if you can call it that:

  1. Unique validation group names PER ROW
  2. Requires the addition of a selected row
  3. Rendering the Submit button to prevent postbacks and isolate the appropriate validation group

我只希望这至少能提供一些信息,也许能让您对服务器控件的多功能性有所了解。

快乐编程...

后面的代码:

namespace WebApplication3
{
    public partial class _Default : Page
    {
        protected void Page_Load( object sender, EventArgs e )
        {
            if ( !Page.IsPostBack )
            {
                List<Parts> ListOfParts = new List<Parts>( new Parts[ ] {
                            new Parts(0, 0),
                            new Parts(0, 0),            
                            new Parts(0, 0) } );

                gvPartsToOrderDetail.DataSource = ListOfParts;
                gvPartsToOrderDetail.DataBind();
            }
        }

        protected void Button1_PreRender( object sender, EventArgs e )
        {
            Button1.OnClientClick = string.Format( "return Page_ClientValidate('vgSubmit_{0}')", gvPartsToOrderDetail.SelectedIndex );
        }
    }

    //------------------------------------------------------------
    // Dummy data class
    //
    public class Parts {
        public Parts( int ticketNo, int status ) {
            TicketNo = ticketNo;
            Status = status;
        }

        public int TicketNo { get; set; }
        public int Status { get; set; }
    }
}

和标记:

<%@ Page Title="Home Page" Language="C#" MasterPageFile="~/Site1.Master" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebApplication3._Default" %>

<asp:Content runat="server" ID="BodyContent" ContentPlaceHolderID="ContentPlaceHolder1">
    <asp:GridView ID="gvPartsToOrderDetail" runat="server" AutoGenerateColumns="False" 
        AutoGenerateSelectButton="True" ClientIDMode="Predictable">
        <Columns>
            <asp:TemplateField HeaderText="Ticket">
                <ItemTemplate>
                    <asp:TextBox ID="tbxTicketNo" runat="server" Text='<%# Bind("TicketNo") %>'></asp:TextBox>
                    <asp:RequiredFieldValidator ID="rfvTxtTicketNo" runat="server" 
                        ErrorMessage="RequiredFieldValidator" Text="*"
                        ControlToValidate="tbxTicketNo"
                        ValidationGroup='<%# string.Format("vgSubmit_{0}", Container.DataItemIndex) %>'>
                    </asp:RequiredFieldValidator>
                        
                </ItemTemplate>
            </asp:TemplateField>
            <asp:TemplateField HeaderText="Parts Status">
                <ItemTemplate>
                    <asp:DropDownList ID="ddlPartStatus" runat="server">
                        <asp:ListItem Text="[ Select ]" Value="0"></asp:ListItem>
                        <asp:ListItem Text="Ordered" Value="1"></asp:ListItem>
                    </asp:DropDownList>
                </ItemTemplate>
            </asp:TemplateField>
        </Columns>

    </asp:GridView>

    <asp:Button ID="btnSubmit" runat="server" Text="Button" 
        OnClientClick='See code in PreRender' 
        OnPreRender="btnSubmit_PreRender" />

</asp:Content>