Пользовательский валидатор в Composite Control не запускается

Я сильно застрял в середине проекта с этой проблемой. Много гуглил, но не нашел решения.

Моя цель - создать составной элемент управления с меткой, текстовым полем, двумя обязательными для проверки полями и настраиваемым валидатором. Мой пользовательский управляющий код выглядит следующим образом:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace AFGISServerControl
{
    [ToolboxData("<{0}:ValidatorTextBox runat="\""server\"> </{0}:ValidatorTextBox>")]
    public class ValidatorTextBox : CompositeControl
    {
        private TextBox InputTextBox;
        private Label InputLabel;
        private RequiredFieldValidator RequiredValidator1;
        private RequiredFieldValidator RequiredValidator2;
        private CustomValidator cv;
        private static readonly object EventValidateKey = new object();

        protected override void OnLoad(EventArgs e)
        {
            EnsureChildControls();
            base.OnLoad(e);
        }
        protected override void CreateChildControls()
        {
            Controls.Clear();
            InputTextBox = new TextBox();
            InputLabel = new Label();
            InputTextBox.ID = "inputTextBox";
            //InputTextBox.AutoPostBack = true;

            RequiredValidator1 = new RequiredFieldValidator();
            RequiredValidator1.ID = this.ID + "_RFV1";
            RequiredValidator1.ControlToValidate = InputTextBox.ID;
            RequiredValidator1.ValidationGroup = string.Empty;
            RequiredValidator1.Display = ValidatorDisplay.Dynamic;
            RequiredValidator1.ErrorMessage = Caption.ToString() + " is mandatory";

            RequiredValidator2 = new RequiredFieldValidator();
            RequiredValidator2.ID = this.ID + "_RFV2";
            RequiredValidator2.ControlToValidate = InputTextBox.ID;
            RequiredValidator2.Display = ValidatorDisplay.Dynamic;
            RequiredValidator2.ErrorMessage = Caption.ToString() + " is mandatory";

            cv = new CustomValidator();
            cv.ID = this.ID + "_CV";
            cv.ControlToValidate = InputTextBox.ID;
            cv.SetFocusOnError = true;
            cv.Display = ValidatorDisplay.Dynamic;
            cv.ErrorMessage = this.CustomErrorMessage;
            cv.ValidateEmptyText = true;
            cv.ServerValidate += new System.Web.UI.WebControls.ServerValidateEventHandler(this.cv_ServerValidate);

            this.Controls.Add(InputLabel);
            this.Controls.Add(InputTextBox);
            this.Controls.Add(RequiredValidator1);
            this.Controls.Add(RequiredValidator2);
            this.Controls.Add(cv);
        }

        #region properties
        [
        Bindable(true),
        Category("Default"),
        DefaultValue(""),
        Description("Value")
        ]
        public string Text
        {
            get
            {
                EnsureChildControls();
                return InputTextBox.Text;
            }
            set
            {
                EnsureChildControls();
                InputTextBox.Text = value;
            }
        }
        [
        Bindable(true),
        Category("Default"),
        DefaultValue(""),
        Description("Validation Group")
        ]
        public string ValidationGroup
        {
            get
            {
                EnsureChildControls();
                return InputTextBox.ValidationGroup;
            }
            set
            {
                EnsureChildControls();
                InputTextBox.ValidationGroup = value;
                RequiredValidator2.ValidationGroup = value;
                cv.ValidationGroup = value;
            }
        }
        [
        Bindable(true),
        Category("Default"),
        DefaultValue(""),
        Description("Error message for the custom validator.")
        ]
        public string CustomErrorMessage
        {
            get
            {
                EnsureChildControls();
                return cv.ErrorMessage;
            }
            set
            {
                EnsureChildControls();
                cv.ErrorMessage = value;
            }
        }
        [
        Bindable(true),
        Category("Default"),
        DefaultValue(""),
        Description("Validity of custom validator.")
        ]
        public Boolean isValid
        {
            get
            {
                EnsureChildControls();
                return cv.IsValid;
            }
            set
            {
                EnsureChildControls();
                cv.IsValid = value;
            }
        }

        [
        Bindable(true),
        Category("Default"),
        DefaultValue(""),
        Description("The text for the name label.")
        ]
        public string Caption
        {
            get
            {
                EnsureChildControls();
                return InputLabel.Text;
            }
            set
            {
                EnsureChildControls();
                InputLabel.Text = value;
            }
        }
        #endregion

        protected override void RecreateChildControls()
        {
            EnsureChildControls();
        }

        [
        Category("Action"),
        Description("Raised on Text Change")
        ]
        public event ServerValidateEventHandler Validate
        {
            add
            {
                Events.AddHandler(EventValidateKey, value);
            }
            remove
            {
                Events.RemoveHandler(EventValidateKey, value);
            }
        }
        protected virtual void OnValidate(ServerValidateEventArgs args)
        {
            EventHandler ValidateHandler = (EventHandler)Events[EventValidateKey];
            if (ValidateHandler != null)
            {
                ValidateHandler(this, args);
            }
        }
        protected void cv_ServerValidate(object source, ServerValidateEventArgs args)
        {
            OnValidate(args);
        }

        protected override void Render(HtmlTextWriter writer)
        {
            AddAttributesToRender(writer);
            InputLabel.RenderControl(writer);
            InputTextBox.RenderControl(writer);
            RequiredValidator1.RenderControl(writer);
            RequiredValidator2.RenderControl(writer);
            cv.RenderControl(writer);
        }        
    }
}

Мой код aspx

    <cc1:ValidatorTextBox ID="ValidatorTextBox1" runat="server" Caption="Service No"
        CustomErrorMessage="Not Valid" ValidationGroup="test" 
        OnValidate="CVText" />
    <asp:Button ID="Button1" runat="server" Text="Button" />

aspx.cs

Конкретная проблема, с которой сталкиваются

  • Метод кода для события "onvalidate" не запускается
  • Обязательное поле для сообщения об ошибке валидатора отображает только "обязательно", заголовок не имеет префикса.

Буду благодарен за совет.

2 ответа

Решение

После того, как я сломал голову, я изменил весь путь с этим контролем. Ушел вперед с использованием ивалидатора. Это довольно эффективный способ.

Несколько вещей:

  • Вам необходимо вызвать Page.Validate() или запустить обратную передачу с помощью CausesValidation=true для элемента управления источником. Убедитесь, что вы не указали ValidationGroup или не используете "тестовую" ValidationGroup при выполнении проверки.
  • Обязательное поле валидатора настраивается во время CreateChildControls. Ваша подпись вытягивается из введенного текста, который не заполняется до публикации сообщения. Возможно, ваш CreateChildControls происходит до загрузки ViewState. Возможно, вы захотите либо использовать JavaScript для установки текста RequiredFieldValidator, либо использовать обработчик события _TextChanged для обновления сообщения об ошибке при каждом изменении текста. Подход, который вы выбираете, очевидно, зависит от ваших конкретных требований.
Другие вопросы по тегам