我正在尝试编写一个游戏,我有一个ASP(4乘4)表,在每个单元格中,有一个按钮。
当我们运行程序时,在Page_Load()上,每个按钮都会得到一个随机数(显示在其button.text中)。游戏的目标之一是点击按钮,导致它们更改其文本,我设法使用www.example.com方法做到这button.click一点,我的问题是,在每次点击时,虽然预期的目标起作用,我们点击的按钮更改其文本,其余的按钮重新加载并为它们的button. text获取新值。
(ig Page_Load再次运行),有什么提示可以解释为什么会发生这种情况,以及处理这种情况以实现我的目标的最佳方法是什么?
这是我的.aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="main.aspx.cs" Inherits="HM1.main" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Table ID="GameTable" runat="server"></asp:Table>
</div>
</form>
</body>
</html>
字符串
这就是我的main.aspx.cs(请注意,for循环中的所有内容,只是让按钮1-15随机放置的代码,数字16在按钮右上角,同时不可见)
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace HM1
{
public partial class main : System.Web.UI.Page
{
public Button[,] buttons;
protected void Page_Load(object sender, EventArgs e)
{
buttons = new Button[4, 4];
int[] buttonMumbers = new int[buttons.Length];
for (int z=0; z < buttonMumbers.Length; z++)
{
buttonMumbers[z] = z + 1;
}
var rng = new Random();
var indexs = buttonMumbers.Select(x => rng.NextDouble()).ToArray();
Array.Sort(indexs, buttonMumbers);
int counter = 0;
for(int i = 0; i <buttons.GetLength(0); i++){
var row = new TableRow();
for(int j = 0; j<buttons.GetLength(1); j++){
var cell = new TableCell();
var button = buttons[i, j] = new Button();
button.Width = 75;
button.Height = 75;
button.BackColor = Color.DarkCyan;
button.Click += new EventHandler(this.BtnClick);
if(i == j && i==3)
{
break;
}
if (buttonMumbers[counter] == 16)
{
counter++;
button.Text = buttonMumbers[counter].ToString();
}else {
button.Text = buttonMumbers[counter].ToString();
counter++;
}
cell.Controls.Add(button);
row.Controls.Add(cell);
}
GameTable.Controls.Add(row);
}
buttons[3, 3].Visible = false;
}
public void BtnClick(Object sender, EventArgs e) {
Button clickedButton = (Button)sender;
clickedButton.Text = "clicked!";
}
}
}
型
1条答案
按热度按时间lnlaulya1#
你看到的行为不仅是正确的,而且实际上是设计好的。
因此,在网页上单击任何按钮都会导致页面加载事件首先运行,然后您的按钮代码存根将运行。
所以,简单的解决方案是将这样的页面加载代码,只运行在真实的的第一个页面加载是有/添加/使用这个额外的if()代码在该页面加载事件:
字符串
所以,在上面,我加载了一个GridView和一些数据。如果我没有把代码放在Is not post back if块中,那么每次单击按钮时,GridView都会重新加载。
这可能是一个问题,比如说对于一个简单的组合框,如果你在一个页面上有一个组合框(列表),在页面加载时,你加载了组合框中的选项?
然后加载代码将每次运行,并在组合框中重写用户的选择。所以,再一次,这意味着/建议/显示/暗示,而页面加载事件可以自由地用于加载和设置代码和值?
请记住,每次发生回发时都会运行这样的代码。因此,大约99%的页面需要上述所有重要的!IsPostBack存根。
事实上,我很舒服地说,你真的不能建立一个工作的webforms页面没有!IsPostBack代码存根。因为在几乎所有的情况下,我们都希望某些页面设置代码只运行一次,并且只在第一次真实的页面加载时运行。如果每次页面加载时都运行这样的设置代码,那么这样的代码将覆盖您在该加载事件中设置的控件和对象的值。如前所述,任何组合框,复选框,甚至是触发回发的按钮都意味着页面加载首先运行,然后给定控件的代码存根运行。
所以,简单的解决方案是使用上面的!IsPostBack代码存根。
也许我指出了在web表单中使用上述设计的原因,而不是桌面领域。在web领域,你正在处理我们所说的无状态系统。这意味着你有一个所谓的页面生命周期,如果不掌握这个页面生命周期,你就不能为web编写软件!
不像桌面程序中的每个用户都有自己的计算机,CPU和内存?在网络世界中,你为给定页面编写的代码在页面发送到客户端后不会持久!
换句话说,你点击一个按钮,这将开始回发,整个网页将被发送到服务器,服务器将确定是什么网页,然后创建网页类(类背后的代码)。代码运行,页面被发送回客户端,然后页面,变量,内存被处理掉!(是的,代码现在从内存中被吹出)。这意味着该页面中的变量和值现在从内存中删除,并被处理。因此术语“无状态”。
实际上,每次点击按钮(post back)意味着每次都重新创建一个全新的代码示例。网站的每个用户在Web服务器的内存中没有这样的代码的副本。在一个页面被处理并设置为客户端之后,Web服务器现在准备好处理其他用户的其他网页。所以,这里只有一台计算机,不像桌面软件,每个人都有自己的软件副本。
上面解释了为什么每次都要触发页面加载,因为每次都要运行大量的设置代码,因为每次都需要内存,变量,并且代码每次都是从头开始重新运行的。因此,您不能也不要期望代码背后模块中的变量在post之后仍然存在。back完成了所谓的往返。因此,所有的值和变量,甚至页面类都被丢弃了,因此所有的代码和变量都超出了作用域。
这很像你退出一个子程序调用时发生的情况,当你从子程序中退出(返回)时,子程序中的局部变量都被释放并退出作用域。
好吧,在网络世界里,你的整个页面类(代码隐藏)每次都会超出范围!
所以,通常你会需要并希望在页面加载中运行一些设置代码,而不是只运行一次的代码。但通常会有你想每次运行的代码,因为正如所指出的,代码中的所有变量和值在每次回发后都会丢失。