可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
Basically I am not using a MasterPage and I just have a project with a Default.aspx with a few labels, textBoxes etc. I've spent several hours looking for a solution and I have found one, but something in my head still bugs me, that I didn't do it the way I wanted to.
I have no troubles accessing them and setting their properties from the PageLoad.
But I made a class, just like the code snippet below, and it throws me an "Object reference not set to an instance of an object". And I cannot seem to figure out what I am missing.
class Functions
{
public static void myMethod()
{
WebForm1 mainForm = new WebForm1();
mainForm.myTextBox.Text = "Something.";
}
}
I managed to do with like this:
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");
}
}
But it's not about just doing it, it's about learning where I am wrong as I cannot figure it out and I want a simpler way to do it, considering I am very new to ASP.NET. Normally when I am coding basic applications in WinForms - I don't have problems accessing different forms.
And I don't like doing a FindControl() for every control I am trying to access. If there is a simple and yet effective workaround I would love to hear it.
Thank you in advance.
Edit: I've made this example aside from my project, but it's the idea I am trying to accomplish. There might be some small errors in the code snippets, please excuse me.
回答1:
Use the code-behind files for this. Don't tightly couple business logic classes to your user interface.
WebForm1.aspx should have WebForm1.aspx.cs if using c# or WebForm.aspx.vb if using vb, so if you have a TextBox control on WebForm1.aspx, you should be able to access it in the code-behind file (WebForm1.aspx.cs or WebForm1.aspx.vb)
public class Validate
{
public bool IsEmail(string email)
{
//return false if invalid e-mail or true if valid
}
}
Then in your WebForm.aspx.cs, you can call
Validate validate = new Validate();
bool isValidEmail = validate.IsEmail(txtEmail.Text);
Where txtEmail is the control. You can make the Validate class static, so you can just do:
bool isvalidEmail = Validate.IsEmail(txtEmail.Text);
回答2:
Controls on a page get created when processed by the asp.net system. They do not get created just by calling a constructor of the page class. This means that you cannot do what you originally tried - non of the controls will be there. The second version (FindControl) worked because you are using the page which got created properly by asp.net, by accessing HttpContext.Current.Handler.
As others have pointed out, it looks like you are trying to do something the wrong way. Since you say you are new to asp.net, maybe someone here can provide some guidance if you will explain what you need to accomplish (in a functional sense, not in a technical sense)
I should also point out that, even if you were successful in creating the page with a simple constructor call, it would be a new instance of the page, and not the one that your user posted back to you.
回答3:
What you should do is declare your control in the designer or in the code behind. Say, myTextBox is your declared textbox. If you'd like to modify this text box's text you should create a property like so
public string MyTextBoxText
{
get
{
return MyTextBox.Text;
}
set
{
MyTextBox.Text = value;
}
}
Sorry for the formatting,... I keep trying to ctrl+K+D but it's not working ;).
Then you should access the properties and manipulate them through the properties. As others have stated, it'll help to know why you're trying to modify this from other classes, or how you're attempting to go about it. If you want to modify the text box through, say, a presenter, this property will be exposed and can be manipulated while shielding the properties you don't want changed from being exposed (which wouldn't be the case if you exposed the entire control)
回答4:
Passing or accessing controls like this is very wrong. Rather send the data you need to that method via method arguments, or initialize the Functions class with necessary data (for instance: control.Text or something) before calling your methods. What you are also trying to do here is typical Functional programming, without any OOP code. Try to find a good book about OOP and read it first, it will make everything easier for you.
回答5:
Since sometimes you just need an answer and need it now, try this:
class Functions
{
public static void myMethod()
{
WebForm1 myMainForm;
myMainForm = (WebForm1)System.Web.HttpContext.Current.Handler;
TextBox myTextBox = myMainForm.myTextBox;
}
}
The trick is to cast the Handler to the type of the Page, not to the base Page class. Doing this you can access your Page strongly without using FindControl. Since this Functions class can't access the protected properties on the Page, you'll also need to expose their data using public properties as Mike M. suggested.
回答6:
You need to remove the STATIC keyword from your method. Then you will be able to reference the controls directly. :)