从DropDownList继承并添加一个Validator,可能吗?

时间:2014-09-16 21:40:18

标签: c# asp.net custom-controls

我已经创建了继承自它的自定义文本框控件,一切都很好,花花公子。但是,我在使用DropDownList尝试同样的问题时遇到了问题。我在谷歌搜索了大约2个小时,我得到的所有结果都是关于创建复合控件和添加DropDownList的一些糟糕的链接或一些(不完整的)建议,但这也意味着我必须暴露所有事件和我使用的属性,我发现我需要做的事情太过分了,这就是在我的DropDownList控件中添加任何类型 next 的验证器。

为了说明这就是我正在尝试做的事情:

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

namespace Blah
{
    public class ExtendedDropDownList : DropDownList
    {

        private DropDownList _self;
        private CustomValidator _cv;
        public bool Required { get; set; }
        public String FieldName { get; set; }

        protected override void OnInit(EventArgs e)
        {
            _cv = new CustomValidator()
            {
                ControlToValidate = ID,
                EnableClientScript = false,
                ValidationGroup = ValidationGroup,
                ValidateEmptyText = true
            };
            _cv.ServerValidate += new ServerValidateEventHandler(_cv_ServerValidate);
            Controls.Add(_cv);
        }

        private void _cv_ServerValidate(object source, ServerValidateEventArgs args)
        {
            if (Required && String.IsNullOrWhiteSpace(args.Value))
            {
                args.IsValid = false;
                _cv.ErrorMessage = "The field <strong>" + FieldName + "</strong> is required.";
                return;
            }            
        }

    }
}

它抛出一个异常,即DropDownList不能有辅助控件。怎么会?如果TextBox允许吗?

有没有办法在不创建复合控件和重写轮子的情况下做同样的事情? (是的,双关语意图:P)。我假设我可以创建控件,然后在呈现DropDownList之后的渲染阶段将其写入,但我无法找到如何做到这一点,如果它甚至可能(虽然是黑客,我很缺乏我需要完成一个表单生成器上的时间,这需要花费太长时间让我感到非常疲惫:( ...你们知道当我用尽所有可用资源时我就来了。)

提前致谢! :d

1 个答案:

答案 0 :(得分:0)

好的,我设法按照我想要的方式去做,但是从容器的页面获得了一些帮助:

我必须将它添加到我的aspx页面:

<asp:PlaceHolder runat="server" ID="phValidators" />

然后是完成的控件,它将验证器添加到我创建的Page的验证器占位符中,而不是控件本身:

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

namespace Blah
{
    public class ExtendedDropDownList : DropDownList
    {
        private CustomValidator _cv;
        public bool Required { get; set; }
        public String FieldName { get; set; }
        public String ValidatorPlaceHolder { get; set; }

        protected override void OnInit(EventArgs e)
        {
            _cv = new CustomValidator()
            {
                ControlToValidate = ID,
                EnableClientScript = false,
                ValidationGroup = ValidationGroup,
                Display = ValidatorDisplay.None,
                ValidateEmptyText = true
            };
            _cv.ServerValidate += new ServerValidateEventHandler(_cv_ServerValidate);
            if (Parent.FindControl(ValidatorPlaceHolder) != null)
                Parent.FindControl(ValidatorPlaceHolder).Controls.Add(_cv);
            else
                throw new Exception("Cannot find asp:PlaceHolder inside parent with ID '" + ValidatorPlaceHolder + "'");
            base.OnInit(e);
        }

        private void _cv_ServerValidate(object source, ServerValidateEventArgs args)
        {
            if (Required && String.IsNullOrWhiteSpace(args.Value))
            {
                args.IsValid = false;
                _cv.ErrorMessage = "The field <strong>" + FieldName + "</strong> is required.";
                return;
            }            
        }

    }
}

我希望这可以帮助别人:)