首页 > 解决方案 > 为什么在单击按钮时会触发 Page_Load?

问题描述

我有类似的东西

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

当用户单击按钮时,它总是打印“USA”,即使他们在countryTextBox 中写了其他内容,这意味着每次单击按钮(或任何其他事件,我猜)时都会触发 Page_Load()。 通过查看这个
问题, 我知道如何解决这个问题,但为什么会发生这种情况?

标签: c#asp.net

解决方案


该网页位于客户端 Web 浏览器上。当您单击一个按钮时,整个页面将被发送到服务器。现在您的代码不仅可以运行,还可以修改控件,并且可以为所欲为。一旦所有代码运行完毕,浏览器页面就会被发送回客户端。

我经常建议 FirstPage 加载事件会帮助这里的山脉。但是,随着时间的推移,我认为每次都必须触发页面加载是好的,并且该设置实际上有助于并促进了它每次运行的事实。但是,在桌面开发中——从 VB6、.net、甚至是 delphi 和 C++ 桌面形式?页面加载甚至只触发一次。所以是的,Web 表单不能以这种方式工作,这让许多人感到惊讶。底线是页面加载每次都会触发,简单的事情是每次都会将全新的页面发送到服务器。因此,虽然可能有两个事件,但通常需要在这两种情况下运行相当多的页面加载代码。因此,有两个单独的事件会造成同样多的麻烦。

那么对于第一次运行的代码(比如设置文本框值)呢?好吧,如果您每次都需要运行该代码(您可能会!!!),那么您可以将它放在检查 IsPostback 的 if/then 块之外。因此,对于设置诸如默认值之类的代码 - 是的,您需要在 IsPostBack = false 块中使用该代码。

网页就是我们所说的无状态。他们坐在用户桌面上。没有与服务器的实时连接。用户可以关闭该网络浏览器或关闭他们的计算机。当用户关闭浏览器时 - 没有信息或谈话被发送到服务器。因此,您可以让 2 或 2000 个用户在他们的浏览器中输入或编辑 - Web 服务器并不关心、查看甚至知道用户正在做什么。并且网络服务器认为它们没有连接。它们只是一个网页 - 该页面可以关闭 - 服务器甚至不知道用户关闭了网站(没有像桌面软件那样的网页关闭事件)。因此,网页的整个设计都是无状态的 - 并且断开连接。Web 服务器不知道该网页是否仍然打开、正在使用或已关闭。Web 服务器可以做任何事情的唯一时间是您将页面发送回服务器。那时,该网页中的所有内容都从头开始,每次回帖(因此称为无状态)。然而,幸运的是,像文本框这样的东西有所谓的“视图状态”,它们确实可以在这些往返行程中幸存下来。如果控件没有视图状态,那么它们也会在每次回发时丢失它们的值。webforms 的一个非常好的特性是大多数控件都能够保持它们的视图状态(这只是意味着这些控件的值可以在往返过程中存活下来。如果控件没有视图状态,那么它们也会在每次回发时丢失它们的值。webforms 的一个非常好的特性是大多数控件都能够保持它们的视图状态(这只是意味着这些控件的值可以在往返过程中存活下来。如果控件没有视图状态,那么它们也会在每次回发时丢失它们的值。webforms 的一个非常好的特性是大多数控件都能够保持它们的视图状态(这只是意味着这些控件的值可以在往返过程中存活下来。

因此,当您单击按钮时,必须进行整个页面的回发,因为后面运行的任何代码都无法查看/查看/更改表单上控件的值。事实上,我们经常看到有人说运行一个 ajax web 方法(在同一页面中),然后想知道为什么他们的代码(在那个 web 方法中)不能更改控件。实际上你可以编写代码来改变控件,但它只改变服务器端的副本,而坐在用户桌面上的副本并没有改变。事实上,当他们(最终)回发时,背后代码更改的任何内容都会丢失。

因此,当您单击按钮时,页面加载事件将首先运行,然后是您的按钮代码。这就是它的工作原理。

所以 99% 的时间,当我开始在页面加载时输入和编写代码时?

你这样做:(比如说加载一个带有数据表的数据网格)。

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

因此,您必须“假设”和“编写”代码,这意味着每次都会触发页面加载事件。但是,在上面,我们只希望第一次设置代码(加载网格视图)运行一次 - 第一次加载页面。所以现在,页面上可能有 5-6 个按钮,页面加载中的上述代码将不会运行,因为我们检查/测试这是否是回发。

所以整个网页必须到达服务器,否则你的代码不能修改网页上的任何控件或值。一旦该代码运行,页面就会返回客户端,并再次位于用户桌面上。所以单击一个按钮必须将整个网页发送回服务器,否则网页上的控件值无法修改,更糟糕的是,该代码的结果将永远不会显示在浏览器中。所以后面的代码不能只修改一个控件。它首先需要整个网页的副本,然后您可以更改一个(或多个)控件,然后整个页面返回浏览器。因此,如果没有首先拥有包含所有内容的网页的完整副本,您就不能编写代码来仅更改一个控件。但是,您可以使用所谓的更新面板。这将允许您运行仅更新部分页面的代码。然而,即使在这种情况下,页面回发事件也会首先运行——这通常称为部分页面回发。因此,您可以放入更新面板,并在该更新面板中拥有按钮和代码 - 他们只能修改该更新面板内的内容,但您注意到整个页面不会重新绘制或重新刷新。您还可以手动编写 JavaScript ajax 调用代码,它们可以在客户端修改一些控件(甚至在服务器端调用例程)。但是您仍然必须假设在网页到达服务器之前,后面的代码无法看到 + 使用这些控件。这即使在使用更新面板时也适用(后面的代码只能修改更新面板中的控件)。更新面板非常好,因为您不需要 不必连接并手动编写一大堆 ajax 和 JavaScript 代码以允许对网页进行部分更新,而不必导致整个页面回发。但如前所述,即使使用更新的面板,页面加载事件也会触发。因此,在大多数情况下,您通常会在该 postback=false 代码块内编写页面加载和设置代码。


推荐阅读