views:

33

answers:

1

I have a UserControl which contains a TextBox and a CustomValidator.

I would like to set the CustomValidator.ServerValidate to a method in the page that contains the UserControl

I found this code which will allow me to dynamically set the custom validators validation function:

cusvCustom.ServerValidate += new System.Web.UI.WebControls.ServerValidateEventHandler(MethodName);

The problem is that a string value won't work there. It needs to be a reference to the method. Is it possible to use reflection (or some other method) to get a valid reference to the parent controls method using only the string name of it? The reason I want to use the string value of the method name is so I can place the control on the page thusly:

<uc1:TextBoxField ID="tbUserName" runat="server" CustomValidationMethod="ValidateUserName" />

I did some research and I found Type.GetMethod and MethodInfo but I can't get them to work. Primarily because I don't know the type of the parent control and can't figure out how to get it.

EDIT: My code for matt-dot-net

WebUserControl.ascx

<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="WebUserControl.ascx.cs" Inherits="WebApplication1.WebUserControl" %>
<asp:CustomValidator ID="CustomValidator1" runat="server" ErrorMessage="Custom Validation Failed" OnServerValidate="CustomValidator1_ServerValidate" />
<asp:TextBox ID="TextBox1" runat="server" />
<asp:Button ID="Button1" runat="server" Text="Submit" CausesValidation="true" />

WebUsecControl.ascx.cs

using System;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace WebApplication1
{
    public partial class WebUserControl : System.Web.UI.UserControl
    {
        public ServerValidateEventHandler Validating;

        protected void CustomValidator1_ServerValidate(object sender, ServerValidateEventArgs e)
        {
            if (Validating != null)
                Validating(sender, e);
        }
    }
}

TestPage.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="TestPage.aspx.cs" Inherits="WebApplication1.TestPage" %>
<%@ Register Src="~/WebUserControl.ascx" TagName="WebUserControl" TagPrefix="uc1" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
<html xmlns="http://www.w3.org/1999/xhtml"&gt;
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
    <uc1:WebUserControl ID="WebUserControl1" runat="server" OnValidating="WebUserControl1_Validating" />

    </div>
    </form>
</body>
</html>

TestPage.aspx.cs

using System;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace WebApplication1
{
    public partial class TestPage : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            //WebUserControl1.Validating += WebUserControl1_Validating;
        }

        protected void WebUserControl1_Validating(Object sender, ServerValidateEventArgs e)
        {
            e.IsValid = false;
        }
    }
}

As you can see it's almost an exact duplicate of your code. For whatever reason it does not work for me as I have it here. When I click on the button the page reloads and is the same. When I un-comment the one line though and click the button then I see the error message.

A: 

I think this is what you want to do:

WebUserControl.ascx:

<%@ Control Language="C#" AutoEventWireup="true" CodeFile="WebUserControl.ascx.cs" Inherits="WebUserControl" %>
<asp:CustomValidator ID="CustomValidator1" runat="server" ErrorMessage="Custom Validation Failed"
ControlToValidate="TextBox1" OnServerValidate="CustomValidator1_ServerValidate" />
<asp:TextBox ID="TextBox1" runat="server" />
<asp:Button ID="Button1" runat="server" Text="Submit" CausesValidation="true" />

And in your code behind:

public partial class WebUserControl : System.Web.UI.UserControl
{
     public event ServerValidateEventHandler Validating;

     protected void CustomValidator1_ServerValidate(object sender, ServerValidateEventArgs e)
     {
         if (Validating != null)
             Validating(sender, e);
     }
 }

This will allow you to use the control on a page the way you want to:

<uc1:WebUserControl ID="WebUserControl1" runat="server" OnValidating="WebUserControl1_Validating" />

Then in your .aspx.cs code behind:

protected void WebUserControl1_Validating(Object sender, ServerValidateEventArgs e)
{
   //do validation here
}
matt-dot-net
This is actually exactly what I'm looking for and much simpler than how I was thinking it would be handled. The only issue I have at the moment is that it's not working. CustomValidator1_ServerValidate gets called but Validating is always null. Do you have any idea why? Also does OnValidating show up for you in intellisense? It isn't for me.
William
Validating will be null if you have not connected an event handler in your page code.
matt-dot-net
Hmm. Still being weird for me. I copied your code exactly and put "e.IsValid = false;" as my validation so it should always fail. I'm not sure why but it still doesn't work for me unless I add "WebUserControl1.Validating += WebUserControl1_Validating;" to the aspx page Page_Load method. I guess it get's the job done but it would be nice to not have to add to the page load method if possible.
William
Works perfectly for me. Here's the code: http://bit.ly/daNpG8
matt-dot-net
AHA! The code you posted is missing the keyword "event" in "public event ServerValidateEventHandler Validating;" but the files you posted have it. When I added the keyword to my code it started working. Thank you!
William
oh man! I'm so sorry - posting code on here with my IE8 browser is painstaking some time... i will edit. Sorry for the trouble.
matt-dot-net
No problem :) It's always something simple. Your answer is exactly what I was looking for. It's much easier than I thought it was going to be.
William