简体   繁体   English

为什么单击按钮时 Page_Load 会被触发?

[英]Why does Page_Load get fired when clicking on a button?

I have something like我有类似的东西

protected void Page_Load(object sender, EventArgs e){
 country.Text = "USA";
}
protected void Button_Click(object sender, EventArgs e){
 Console.Write(country.Text);
}

and when the user clicks on the button, it always prints "USA", even if they wrote something else in the country TextBox, it means that Page_Load() gets fired each time a button (or any other event, I guess) is clicked.当用户点击按钮时,它总是打印“美国”,即使他们在country文本框中写了其他东西,这意味着每次点击按钮(或任何其他事件,我猜)时都会触发 Page_Load() .
I know how to fix this, by looking at this question, but why does that happen?通过查看这个问题,我知道如何解决这个问题,但为什么会发生这种情况?

The web page is sitting on the client side web browser.该网页位于客户端 Web 浏览器上。 When you click a button, the whole page is sent up to the server.当您单击一个按钮时,整个页面都会发送到服务器。 Now you code behind can not only run, but modify controls, and does whatever you want.现在你背后的代码不仅可以运行,还可以修改控件,为所欲为。 Once all that code is run, then the browser page is sent back down to the client.一旦所有代码运行完毕,浏览器页面就会被发送回客户端。

I have often suggested that a FirstPage load event would have helped mountains here.我经常建议 FirstPage 加载事件会帮助这里的山。 However, over time, I think the page load having to fire each time is fine, and that the setup actually helps and promotes the fact that it runs every time.但是,随着时间的推移,我认为每次都必须触发页面加载是好的,并且设置实际上有助于并促进了它每次运行的事实。 However, in desktop development - from VB6, .net, heck even delphi and C++ desktop forms?但是,在桌面开发中 - 从 VB6、.net、甚至 delphi 和 C++ 桌面形式? The page load even ONLY ever fires one time.页面加载甚至只触发一次。 So yes, it is surprise to many that web forms don't work this way.所以,是的,许多人感到惊讶的是,Web 表单不能以这种方式工作。 The bottom line is that page load fires every time, and the simple matter is a WHOLE NEW fresh page is sent up to the sever EVERY TIME.最重要的是每次都会触发页面加载,简单的事情是每次都将全新的页面发送到服务器。 So, while there could have been two events, often quite a bit of page load code has to run in both cases.因此,虽然可能有两个事件,但在这两种情况下通常必须运行相当多的页面加载代码。 So then having two seperate events would cause just as much trouble.因此,有两个单独的事件会造成同样多的麻烦。

So for code that runs first time (such as setting up the text box value)?那么对于第一次运行的代码(比如设置文本框值)呢? Well, if you need that code to run each time (and you might!!!), then you place it outside of the if/then block that checks for the IsPostback.好吧,如果您每次都需要运行该代码(您可能会!!!),那么您可以将它放在检查 IsPostback 的 if/then 块之外。 So for code to setup things such as defaults - yes, you need that code inside your IsPostBack = false block.因此,对于设置诸如默认值之类的代码 - 是的,您需要在 IsPostBack = false 块中使用该代码。

Web pages are what we call state-less.网页就是我们所说的无状态。 They are sitting on the users desktop.他们坐在用户的桌面上。 There is NO LIVE connection to the server.没有与服务器的实时连接。 The user can close that web browser or turn off their computer.用户可以关闭该 Web 浏览器或关闭他们的计算机。 And when the user closes the browser - no information or talking is sent to the server.当用户关闭浏览器时 - 不会向服务器发送任何信息或谈话。 So you can have 2 or 2000 users typeing or editing in their brwoser - the web server does not care, see or even know that users are doing things.因此,您可以让 2 或 2000 个用户在他们的浏览器中输入或编辑 - Web 服务器并不关心、查看甚至知道用户在做什么。 And the web server considers them NOT CONNECTED.并且 Web 服务器认为它们未连接。 They are just a web page - that page can be closed - the server does not even know the user closed the web site (there is no web page close event like desktop software).它们只是一个网页 - 该页面可以关闭 - 服务器甚至不知道用户关闭了网站(没有像桌面软件那样的网页关闭事件)。 So the whole design of web pages are sate-less - and disconnneced.所以网页的整个设计是无状态的 - 并且是断开的。 The web server does not know if that web page is still open, being used, or been closed. Web 服务器不知道该网页是否仍然打开、正在使用或已关闭。 The ONLY time the web server can do ANYTHING is if you send the page back up to the server. Web 服务器可以做任何事情的唯一时间是您将页面发送回服务器。 At that point EVERYTHING in that web page starts over from scratch every post back (hence the term state-less).那时,该网页中的所有内容都从头开始,每次回帖(因此称为无状态一词)。 However, thankfully things like a text box have what is called a "view state" and they DO survive those round trips.然而,值得庆幸的是,像文本框这样的东西具有所谓的“视图状态”,并且它们确实在这些往返行程中幸存下来。 If a control does not have a view state, then they also would lose their values on each post back.如果控件没有视图状态,那么它们也会在每次回发时丢失其值。 One VERY nice feature of webforms is most controls have the ability to keep their viewstate (that just means the value(s) of such controls can survive a round trip. webforms 的一个非常好的特性是大多数控件都能够保持它们的视图状态(这只是意味着这些控件的值可以在往返过程中幸存下来。

So when you click a button, then a whole page postback has to occur, since any code running behind would not be able to look at/ see / change the value of controls on the form.因此,当您单击一个按钮时,必须发生整个页面回发,因为后面运行的任何代码都无法查看/查看/更改表单上控件的值。 In fact, we often seen someone say run a ajax web method (in the same page) and then wonder why their code behind (in that web method) can't change controls.事实上,我们经常看到有人说运行一个ajax web方法(在同一个页面中)然后想知道为什么他们后面的代码(在那个web方法中)不能改变控件。 In fact you can write code to change controls, but it only changing the server side copy, and the copy sitting on the user's desktop is not changed.实际上你可以编写代码来改变控件,但它只是改变了服务器端的副本,而坐在用户桌面上的副本并没有改变。 In fact, when they do (eventually) a post back, anything the code behind changed is lost.事实上,当他们(最终)回发时,后面更改的任何代码都会丢失。

So when you click on a button, the page load event will run FIRST and then your button code.因此,当您单击按钮时,页面加载事件将首先运行,然后是您的按钮代码。 This is how it works.这就是它的工作原理。

So 99% of the time, when I start typing and writing code in page load?那么 99% 的情况下,当我在页面加载时开始键入和编写代码时?

You do this: (say to load up a datagrid with a data table).你这样做:(比如加载一个带有数据表的数据网格)。

if IsPostBack = False then
   GridView1.Datasource = myrst("SELECT * from tblhotels")
   GridView1.Databind()
End if

So, you have to "assume" and "write" code that means the page load event fires every time.因此,您必须“假设”和“编写”代码,这意味着每次都会触发页面加载事件。 However, in above, we only want the first time setup code (to load up a gridview) to run one time - the first time the page loads.但是,在上面,我们只希望第一次设置代码(加载 gridview)运行一次 - 第一次加载页面。 So now, you might have 5-6 buttons on the page, and the above code in the page load will not run since we check/test if this is a post back.所以现在,您可能在页面上有 5-6 个按钮,并且页面加载中的上述代码将不会运行,因为我们检查/测试这是否是回发。

So the whole web page has to travel up to the server, else your code behind can't modify any controls or values on the web page.因此整个网页必须传送到服务器,否则您的代码无法修改网页上的任何控件或值。 Once that code runs, then the page travels back down to the client side and is again just sitting on the users desktop.一旦该代码运行,页面就会返回到客户端并再次停留在用户桌面上。 So clicking a button HAS to send the whole web page back to the server, else the values of controls on the web page could not be modified, and worse the results of that code would never be displayed back in the browser.因此,单击按钮必须将整个网页发送回服务器,否则网页上控件的值将无法修改,更糟糕的是,该代码的结果永远不会显示在浏览器中。 So code behind can't JUST modify one control.所以后面的代码不能只修改一个控件。 it needs a whole copy fo the web page first, and then you can change a control (or several) and then the whole page makes the trip back to the browser.它首先需要一个完整的网页副本,然后您可以更改一个(或多个)控件,然后整个页面返回到浏览器。 So you can't write code to JUST change one control without first having a WHOLE copy of the web page with everything.因此,您不能编写代码来仅更改一个控件,而无需先拥有包含所有内容的网页的完整副本。 However, you can use what is called a update panel.但是,您可以使用所谓的更新面板。 This will allow you to run code that updates JUST part of the page.这将允许您运行仅更新页面一部分的代码。 However, even in that case, the page post back event does run first - this is often called a partial page post back.但是,即使在这种情况下,页面回发事件也会首先运行 - 这通常称为部分页面回发。 So you can drop in a update panel, and have buttons and code in that update panel - they can only modify things inside of that update panel, but you note that the whole page does not replot or re-fresh.因此,您可以放入更新面板,并在该更新面板中添加按钮和代码 - 它们只能修改该更新面板内的内容,但您会注意到整个页面不会重新绘制或重新刷新。 You can also hand code JavaScript ajax calls, and they can client side modify some controls (and even call routines server side).您还可以手动编写 JavaScript ajax 调用,并且可以在客户端修改一些控件(甚至调用服务器端的例程)。 But you still have to assume that code behind can NOT see + use those controls until such time the web page travels up to the server.但是您仍然必须假设后面的代码无法看到并使用这些控件,直到网页到达服务器为止。 This applies even when using a up-date panel (the code behind can only modify controls in the update panel).这甚至在使用更新面板时也适用(背后的代码只能修改更新面板中的控件)。 Update panels are very nice in that you don't have to wire up and hand code a whole bunch of ajax and JavaScript to allow partial updates of the web page and not have to cause a full page post back.更新面板非常好,因为您不必连接和手工编写一大堆 ajax 和 JavaScript 来允许部分更新网页,而不必导致整个页面回发。 But as noted, even when using a up-date panel, the page load event does fire.但如前所述,即使使用更新面板,页面加载事件也会触发。 So for the most part, you in general write the page load and setup code inside of that postback=false code block.因此,在大多数情况下,您通常在 postback=false 代码块中编写页面加载和设置代码。

This is what the ASP.Net Button class tells us about the Button class:这是 ASP.Net Button 类告诉我们关于Button类的内容:

By default, a Button control is a Submit button.默认情况下,Button 控件是一个提交按钮。 A Submit button does not have a command name (specified by the CommandName property) associated with the button and simply posts the Web page back to the server.You can provide an event handler for the Click event to programmatically control the actions performed when the Submit button is clicked.提交按钮没有与按钮关联的命令名称(由 CommandName 属性指定),它只是将网页发送回服务器。您可以为 Click 事件提供一个事件处理程序,以编程方式控制提交时执行的操作按钮被点击。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM