【问题标题】:How can I access the controls on my ASP.NET page from a class within the solution?如何从解决方案中的类访问 ASP.NET 页面上的控件?
【发布时间】:2011-06-15 19:02:35
【问题描述】:

基本上我没有使用 MasterPage,我只是有一个带有 Default.aspx 的项目,带有一些标签、文本框等。我花了几个小时寻找解决方案,我找到了一个解决方案,但我脑子里有些东西仍然困扰着我,我没有按照自己想要的方式做。

从 PageLoad 访问它们并设置它们的属性没有任何问题。

但是我创建了一个类,就像下面的代码 sn-p 一样,它会抛出一个“对象引用未设置为对象的实例”。而且我似乎无法弄清楚我错过了什么。

   class Functions 
    {
       public static void myMethod()
       {
            WebForm1 mainForm = new WebForm1();
            mainForm.myTextBox.Text = "Something.";
       }
    }

我设法做到了:

   class Functions 
    {
       public static void myMethod()
       {
           System.Web.UI.Page myMainForm;
           myMainForm = (System.Web.UI.Page)System.Web.HttpContext.Current.Handler;
           TextBox myTextBox = (TextBox)myMainForm.FindControl("myTextBox");
       }
    }

但这不仅仅是做它,它是关于了解我错在哪里,因为我无法弄清楚,我想要一种更简单的方法来做到这一点,考虑到我对 ASP.NET 非常陌生.通常,当我在 WinForms 中编写基本应用程序时 - 我在访问不同的表单时没有问题。

而且我不喜欢为我尝试访问的每个控件执行 FindControl()。如果有一个简单而有效的解决方法,我很想听听。

提前谢谢你。

编辑:我已经在我的项目之外制作了这个示例,但这是我想要实现的想法。代码sn-ps可能有一些小错误,请见谅。

【问题讨论】:

  • 你想完成什么?这一切都错了。
  • 我也不明白你在做什么。
  • 我只是想从一个方法中访问控件,正如我解释的那样。整个项目及其想法更大,但与我的要求无关。
  • 对不起,如果我让你们难以理解,显然太新了,无法正确解释。
  • 但是您实际上想做什么?如果您只是想访问某些文本框的“Text”属性,那么只需将txtMyTextBox.Text 传递给该方法。如果您需要访问整个控件(仍然不是一个好主意),则将整个 txtMyTextBox 传递给该方法。

标签: c# asp.net class textbox reference


【解决方案1】:

为此使用代码隐藏文件。不要将业务逻辑类与用户界面紧密耦合。

如果使用 c#,WebForm1.aspx 应该有 WebForm1.aspx.cs,如果使用 vb,应该有 WebForm.aspx.vb,所以如果你在 WebForm1.aspx 上有一个 TextBox 控件,你应该能够在代码隐藏中访问它文件(WebForm1.aspx.cs 或 WebForm1.aspx.vb)

public class Validate
{
    public bool IsEmail(string email)
    {
        //return false if invalid e-mail or true if valid
    }
}

然后在你的WebForm.aspx.cs中,你可以调用

 Validate validate = new Validate();
 bool isValidEmail = validate.IsEmail(txtEmail.Text);

其中 txtEmail 是控件。您可以将 Validate 类设为静态,因此您可以这样做:

 bool isvalidEmail = Validate.IsEmail(txtEmail.Text);

【讨论】:

  • 这正是我要问的,我无法访问它,这些是我的代码隐藏中的代码 sn-ps,这是在 Default.aspx.cs 我只能访问文本框或标签如果我写在“Page_Load”部分。如果我在其中创建一个类和一个方法,并键入例如 textBox1.Text,它不会将其识别为现有控件。
  • @Synthel,就像其他人当时所说的那样,你做的一切都错了。分开你的顾虑。将 bll 或 dal 类保留在代码隐藏文件之外。
  • @Xaisoft 所以将它们作为单独的项目添加到解决方案中,是你的建议,而不是把它们放在 Page_Load 之下?
  • @Synthel,是的,这就是我的建议。例如,您可能有一个包含验证控件输入的方法的类,因此您可以创建具有验证方法的 Validate.cs 类,然后使用 Validate.cs 的方法对控件进行操作。我举个例子。
  • @Synthel,请记住这一点,如果您将类放在代码隐藏文件中,您将失去重用能力。这意味着,如果您有一个在许多控件中具有通用功能的类,您是要将该类复制到每个 Webform 中,还是拥有一个可以从任何地方访问的类。
【解决方案2】:

页面上的控件在由 asp.net 系统处理时创建。它们不是通过调用页面类的构造函数来创建的。这意味着您无法执行您最初尝试的操作 - 不会有任何控件。第二个版本(FindControl)之所以有效,是因为您正在使用由 asp.net 通过访问 HttpContext.Current.Handler 正确创建的页面。

正如其他人指出的那样,您似乎正在尝试以错误的方式做某事。既然你说你是 asp.net 的新手,也许这里有人可以提供一些指导,如果你能解释你需要完成什么(在功能意义上,而不是在技术意义上)

我还应该指出,即使您通过简单的构造函数调用成功地创建了页面,它也将是该页面的一个新实例,而不是您的用户发回给您的那个实例。

【讨论】:

  • 很高兴知道它为什么会起作用,但得知我对自己的做法完全错误,这并不好。如果我试图解释整个概念,我可能只会更激怒一些人。
【解决方案3】:

您应该做的是在设计器或后面的代码中声明您的控件。说, myTextBox 是您声明的文本框。如果你想修改这个文本框的文本,你应该像这样创建一个属性

public string MyTextBoxText
{
   get
   {
      return MyTextBox.Text;
   }
   set
   {
      MyTextBox.Text = value;
   }
}

抱歉格式化,...我一直在尝试按 ctrl+K+D 但它不起作用;)。

然后您应该访问属性并通过属性操作它们。正如其他人所说,这将有助于了解您为什么要尝试从其他类中修改它,或者您是如何尝试进行修改的。如果您想通过演示者修改文本框,则该属性将被公开并且可以在屏蔽您不希望更改的属性被公开的同时进行操作(如果您公开了整个控制)

【讨论】:

  • 谢谢你的提示,我现在试试看效果如何。也感谢您与其他人不同,对初学者保持友好。
  • 我有一个问题,这是否被认为是一种好习惯。我的意思是,如果我想获得类似的结果,我应该只传递所需的属性而不是传递整个控件?
  • 是的,当然,除非有特定原因您需要整个控件,否则您应该只公开需要修改的属性(通常每个控件只有一个,例如 .Text、.Checked 等)
  • 我刚刚尝试在主页的 Designer.cs 文件中公开此类属性,但是,我仍然无法在方法中访问公开的属性。我的想法是创建一个 Initialize() 以及可能在页面加载时调用的其他几个方法。例如,这些方法中的一个将根据 LinqToSql 查询在 TextBox 中放置一个名称。但是,即使我按照您的建议公开了 TextBox.Text 属性,我也无法调用它。它仍然抛出一个空引用。我又错过了什么?
【解决方案4】:

像这样传递或访问控件是非常错误的。而是通过方法参数将您需要的数据发送到该方法,或者在调用您的方法之前使用必要的数据(例如:control.Text 或其他东西)初始化 Functions 类。您在这里还尝试做的是典型的函数式编程,没有任何 OOP 代码。试着找一本关于 OOP 的好书先读一读,它会让你的一切变得更轻松。

【讨论】:

  • 感谢您的建议,我会进一步阅读。但我相信我解释的非常错误,每个人都误解了我。
【解决方案5】:

因为有时你只需要一个答案,现在就需要它,试试这个:

class Functions 
{
   public static void myMethod()
   {
       WebForm1 myMainForm;
       myMainForm = (WebForm1)System.Web.HttpContext.Current.Handler;
       TextBox myTextBox = myMainForm.myTextBox;
   }
}

诀窍是将 Handler 转换为 Page 的类型,而不是基 Page 类。这样做您可以在不使用 FindControl 的情况下强烈访问您的页面。由于此 Functions 类无法访问页面上的受保护属性,因此您还需要按照 Mike M. 的建议使用公共属性公开其数据。

【讨论】:

  • 谢谢凯文,如果我不知道如何正确操作,我会试试这个。现在我有点担心我在逻辑上做错了所以试图找出正确的方法而不是学习错误的方法。
  • 再次感谢 Kevin,您、Mike 和 Xisoft 都非常有用,但我不知道如何同时给大家投票。 :)
【解决方案6】:

您需要从方法中删除 STATIC 关键字。然后您将能够直接引用控件。 :)

【讨论】:

    猜你喜欢
    • 2013-07-18
    • 2013-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-02
    相关资源
    最近更新 更多