如何使用ASP.NET从一个用户控件调用另一个用户控件中的方法?

5

我有两个用户控件:UserControl1UserControl2,这些控件添加在 Page.aspx 中。

UserControl1: 该用户控件包含隐藏文本框的方法。此方法名为 "HideTextbox"。

UserControl2: 我想从 UserControl2 调用方法 "HideTextBox"。

如何从 UserControl2 调用方法 HideTextBox


UserControl2是不是在UserControl1中作为子控件? - Darren Griffith
用户控件2与用户控件1在Page.aspx中处于同一级别。 - Jenan
6个回答

6
只有当两者都是用户控件或服务器控件时,或者您正在从用户控件查找服务器控件时,此方法才适用。(不能从服务器控件中查找,因为您无法获取对asp.usercontrol_xx程序集的引用)
首先获取对父页面的引用(通常可以使用“this.Parent”实现)。 然后在父级上进行递归查找控件,以找到其类型为“UserControl2”的控件。 示例代码:
//this for extension method
public static UserControl2 FindUserControl2Recursive(this Control root)
{
    var uc2 = root as ASP.UserControls_UserControl2_ascx;
    if (uc2 != null)
    {
        return uc2;
    }
    foreach (var control in root.Controls)
    {
        uc2 = control.FindUserControl2Recursive();
        if (uc2 != null)
        {
            return uc2;
        }
    }
    return null;
}

一旦您获得了Usercontrol2的引用,您就可以轻松调用公共方法。

6
这个问题可以通过在UC2中创建自定义事件,并在主页面上消耗该事件来调用UC1的隐藏方法来解决。
你需要在你的用户控件中声明一个委托。
public delegate void HideTextBoxEventHandler(object sender, EventArgs e);

然后为你创建的代理定义事件。
public event HideTextBoxEventHandler HideTextBox;

在代码中想要隐藏文本框的地方,您需要调用该事件:

if (this.HideTextBox != null) // if there is no event handler then it will be null and invoking it will throw an error.
{
   EventArgs e = new EventArgs();
   this.HideTextBox(this, e);
}

然后从主页面创建一个事件处理方法

protected void UserControl2_HideTextBox(Object sender, EventArgs e)
{
   UC1.InvokeHideTextBox();  // this is the code in UC1 that does the hiding
}

您需要在页面加载或者加载UC2的地方进行添加。

UC2.HideTextBox += new UserControl2.HideTextBoxEventHandler(this.UserControl2_HideTextBox);

1
我会在控件上声明接口,该接口知道如何隐藏文本框,就像这样:
public interface ITextBoxHider
{
  void HideTextBoxes();
}

接下来在UserControl1上实现这个接口,当你想要隐藏文本框时,枚举表单上的所有控件并找到一个实现了ITextBoxHider接口的控件,然后简单地调用该方法:

帮助方法将枚举所有控件:

public static IEnumerable<Control> GetAllChildren(Control parent)
{
  foreach (Control control in parent.Controls)
  {
    foreach (Control grandChild in GetAllChildren(control))
        yield return grandChild;

    yield return control;
  }
}

使用该方法并从UserControl2调用HideTextBoxes:

var hider = GetAllChildren(this.Page).FirstOrDefault(ct => ct is ITextBoxHider);
if (hider != null)
  (hider as ITextBoxHider).HideTextBoxes();

0

在用户控件2上

UC1Class UserControl = Parent.FindControl("UC1_Name") as UC1Class;
UserControl.HideTextbox();

或缩短

(Parent.FindControl("UC1_Name") as UC1Class).HideTextbox();

在用户控件1上

public void HideTextbox()
{
    ....Do Something
}

-1

首先,您需要将HideTextBox()方法从私有方法更改为公共方法。

然后调用UserControl1.HideTextBox()方法。

更新: 我之前没有清楚地说明如何获取对UserControl1的引用。在我的项目中,我创建了一个声明了我要调用的方法的接口,因此我的代码如下:

IUserControl1 uc1 = (IUserControl1)this.Parent.FindControl("ucOne");
uc1.HideTextBox();

请确保您的UserControl1从接口派生: public partial class UserControl1 : System.Web.UI.UserControl, IUserControl1


4
没错,但我认为真正的问题是从UserControl1获取对UserControl2的引用。 - Robert Harvey
罗伯特,你是对的。这个错误是“对象引用未设置为对象的实例”。 - Jenan

-1
如果您想使用Usercontrol对象访问方法,您必须像这样进行注册。
UserControl1 uc = new UserControl1();
uc.HideTextBox();

你需要将 HideTextBox() 声明为 public。

另外,你需要在 Web 表单中添加一个指令,告诉它你要动态加载用户控件。因此,在 Web 表单中添加以下指令。

<%@ Reference Control = "WebUserControl1.ascx" %>

希望这能有所帮助


1
UC1和UC2都存在于同一页上,但彼此不知道对方的存在。按照您所描述的方法调用该方法将在UC1的新实例中调用该方法,而不是页面上的实例。 - Chad

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接