[英]asp.net 3.5 Am I “Getting” this?
我正在使用 Visual Studio 2008 学习 ASP.NET 3.5 和 C#。我学到的大部分东西都是通过 MSDN 获得的。 我正在尝试开发一个 web 页面,该页面将允许用户创建用于 RPG 游戏的角色。 用户应该能够分配属性、购买物品等。当用户完成后,站点将使用用户数据格式化一个可打印的字符表。
现在,我仍然围绕着这些东西,想知道我是否走在正确的轨道上——如果有人想看看我到目前为止所拥有的东西并发表评论,那就太棒了。 我对我做错或效率低下的任何事情、糟糕的设计、糟糕的代码以及我可以改进的方法都感兴趣。 但大多数情况下,我只想知道我是否走在正确的轨道上,而不是滥用这项技术。
以下是我到目前为止的代码。 它允许用户将一定数量的点分配给 4 个统计数据。
主页:
<%@ Page Language="C#"
AutoEventWireup="true"
CodeFile="Default.aspx.cs"
Inherits="_Default"
enableSessionState="true"
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<!-- MPCP/Bod/Evasion/Masking/Sensor -->
<asp:Label ID="MPCP_Rating" runat="server" Text="" ></asp:Label>
<br /> <br />
<asp:Label ID="PersonaPool" runat="server" Text="" ></asp:Label>
<br /> <br />
<!-- TODO: Format into table -->
Bod:
<asp:TextBox ID="Bod" runat="server" ontextchanged="Bod_TextChanged"
width="25px">0</asp:TextBox>
<asp:Button ID="BodInc" runat="server" Text="+"
OnClick="Bod_Inc" />
<asp:Button ID="BodDec" runat="server" Text="-"
OnClick="Bod_Dec"/>
<br /> <br />
Evasion:
<asp:TextBox ID="Evasion" runat="server" ontextchanged="Evasion_TextChanged"
width="25px">0</asp:TextBox>
<asp:Button ID="EvasionInc" runat="server" Text="+"
OnClick="Evasion_Inc" />
<asp:Button ID="EvasionDec" runat="server" Text="-"
OnClick="Evasion_Dec" />
<br /> <br />
Masking:
<asp:TextBox ID="Masking" runat="server" ontextchanged="Masking_TextChanged"
width="25px">0</asp:TextBox>
<asp:Button ID="MaskingInc" runat="server" Text="+"
OnClick="Masking_Inc" />
<asp:Button ID="MaskingDec" runat="server" Text="-"
OnClick="Masking_Dec" />
<br /> <br />
Sensor:
<asp:TextBox ID="Sensor" runat="server" ontextchanged="Sensor_TextChanged"
width="25px">0</asp:TextBox>
<asp:Button ID="SensorInc" runat="server" Text="+"
OnClick="Sensor_Inc" />
<asp:Button ID="SensorDec" runat="server" Text="-"
OnClick="Sensor_Dec" />
<br /> <br />
<asp:Button ID="Submit" runat="server" Text="Submit" />
</div>
</form>
</body>
</html>
代码隐藏:
using System;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
public partial class _Default : System.Web.UI.Page
{
private DeckData deck;
public _Default()
{
}
// Page events
protected void Page_Load(object sender, EventArgs e)
{
deck = (DeckData)(System.Web.HttpContext.Current.Session["Deck"]);
MPCP_Rating.Text = "MPCP Rating: " + deck.MPCP.ToString();
UpdateAvailPersona();
}
protected void Unload(object sender, EventArgs e)
{
}
// Helper functions
protected void ChangeAttribute(DeckData.Attributes atr, bool inc)
{
if (inc == true)
deck.IncAttribute(atr);
else
deck.DecAttribute(atr);
UpdateAvailPersona();
switch (atr)
{
case DeckData.Attributes.Bod:
Bod.Text = deck.Bod.ToString();
break;
case DeckData.Attributes.Evasion:
Evasion.Text = deck.Evasion.ToString();
break;
case DeckData.Attributes.Masking:
Masking.Text = deck.Masking.ToString();
break;
case DeckData.Attributes.Sensor:
Sensor.Text = deck.Sensor.ToString();
break;
}
}
protected void UpdateAvailPersona()
{
PersonaPool.Text = "Persona Pool: " + deck.PersonaMax.ToString() +
" / " + (deck.CalculateAvailPersona()).ToString();
}
// Control Events
protected void Bod_Dec(object sender, EventArgs e)
{
ChangeAttribute(DeckData.Attributes.Bod, false);
}
protected void Bod_Inc(object sender, EventArgs e)
{
ChangeAttribute(DeckData.Attributes.Bod, true);
}
protected void Evasion_Dec(object sender, EventArgs e)
{
ChangeAttribute(DeckData.Attributes.Evasion, false);
}
protected void Evasion_Inc(object sender, EventArgs e)
{
ChangeAttribute(DeckData.Attributes.Evasion, true);
}
protected void Masking_Dec(object sender, EventArgs e)
{
ChangeAttribute(DeckData.Attributes.Masking, false);
}
protected void Masking_Inc(object sender, EventArgs e)
{
ChangeAttribute(DeckData.Attributes.Masking, true);
}
protected void Sensor_Dec(object sender, EventArgs e)
{
ChangeAttribute(DeckData.Attributes.Sensor, false);
}
protected void Sensor_Inc(object sender, EventArgs e)
{
ChangeAttribute(DeckData.Attributes.Sensor, true);
}
App-Data(只是 DeckData 类)
using System;
using System.Data;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
/// <summary>
/// Store deck related data and provide methods for adjusting deck data
/// </summary>
public class DeckData
{
// Set persona multiplier, determines max persona pool
private const uint _PersonaMultiplier = 3;
public DeckData(uint MPCP)
{
_MPCP = MPCP;
_Bod = _Evasion = _Masking = _Sensor = 0;
CalculateMaxPersona();
}
// MPCP/Bod/Evasion/Masking/Sensor
public enum Attributes
{
MPCP,
Bod,
Evasion,
Masking,
Sensor
}
private uint _MPCP;
private uint _Bod;
private uint _Evasion;
private uint _Masking;
private uint _Sensor;
private uint _PersonaMax;
/// <summary>
/// Acessor/Modifiers
/// </summary>
public uint MPCP
{
get { return _MPCP; }
set { _MPCP = value; }
}
public uint Bod
{
get { return _Bod; }
set { _Bod = value; }
}
public uint Evasion
{
get { return _Evasion; }
set { _Evasion = value; }
}
public uint Masking
{
get { return _Masking; }
set { _Masking = value; }
}
public uint Sensor
{
get { return _Sensor; }
set { _Sensor = value; }
}
public uint PersonaMax
{
get { return _PersonaMax; }
}
/// <summary>
/// Calculate available persona. Must be called before changing attribs to ensure
/// persona pool remains valid
/// </summary>
/// <returns></returns>
public uint CalculateAvailPersona()
{
// Total deck attribs
uint attrTotal = _Bod + _Evasion + _Masking + _Sensor;
return _PersonaMax - attrTotal;
}
/// <summary>
/// Recalculate max persona
/// </summary>
private uint CalculateMaxPersona()
{
_PersonaMax = _MPCP * _PersonaMultiplier;
return _PersonaMax;
}
/// <summary>
/// Increment attribute by 1 point
/// </summary>
/// <param name="atr">
/// The attribute to increment
/// </param>
/// <returns>
/// false if no Persona available
/// true if attribute successfully incremented
/// </returns>
public bool DecAttribute(DeckData.Attributes atr)
{
uint availPersona = CalculateAvailPersona();
if (availPersona == _PersonaMax)
return false;
switch (atr)
{
case Attributes.MPCP:
break;
case Attributes.Bod:
if (_Bod > 0) // Check for underflow
_Bod -= 1;
break;
case Attributes.Evasion:
if (_Evasion > 0)
_Evasion -= 1;
break;
case Attributes.Masking:
if (_Masking > 0)
_Masking -= 1;
break;
case Attributes.Sensor:
if (Sensor > 0)
_Sensor -= 1;
break;
}
// Check to see if we updated an attribute using cached persona
if(availPersona != CalculateAvailPersona())
return true;
return false;
}
public bool IncAttribute(DeckData.Attributes atr)
{
uint availPersona = CalculateAvailPersona();
if (availPersona == 0)
return false;
switch (atr)
{
case Attributes.MPCP:
break;
case Attributes.Bod:
_Bod += 1;
break;
case Attributes.Evasion:
_Evasion += 1;
break;
case Attributes.Masking:
_Masking += 1;
break;
case Attributes.Sensor:
_Sensor += 1;
break;
}
return true;
}
}
谢谢!
如果您擅长 html,请放弃 webforms 并使用像asp.net mvc或fubu mvc这样的 mvc 框架。
如果你不擅长 html,学习 html,放弃 webforms,使用 mvc 框架。
我刚刚快速浏览了您的代码,其中一件事确实是使用 web 应用程序所涉及的服务器回发数量。 对属性的每次更改都会导致页面被提交回服务器,虽然技术上没问题,但不会带来很好的用户体验。
您可能想要研究允许用户进行所有修改然后将它们一起提交的技术(例如在客户端使用 javascript 来维护属性点的分布),或者考虑使用 AJAX 异步回发对服务器的修改导致更流畅的用户体验。
编辑:使用 model 您可以使用 Button 控件 Command 事件而不是 Click 事件。 这将允许您为可以在后面的代码中恢复的每个按钮分配一个 CommandName 和 CommandArgument 值。 这将允许您为每个按钮只有一个事件方法,该方法可以决定要更改哪个属性以及如何更改这些属性:
<asp:Button ID="BodInc" runat="server" CommandArgument="Increase"
CommandName="Bod" oncommand="AttributeButton_Command" Text="+" />
<asp:Button ID="BodDec" runat="server" CommandArgument="Increase"
CommandName="Bod" oncommand="AttributeButton_Command" Text="-" />
后面的代码:
protected void AttributeButton_Command(object sender, CommandEventArgs e)
{
string attriubuteName = e.CommandName;
string action = e.CommandArgument;
// Do stuff
}
我会提出的一个建议是查看使用 javascript 来增加/减少标记中的计数器,然后使用表单提交时文本框的值对 model 进行更新。 正如@Andy 建议的那样,您也可以通过 AJAX 进行更新以减少可见的 UI 闪烁,但鉴于您拥有的简单规则,我认为在客户端执行此操作并回发一次是 go 的方法。
除非您希望用户直接输入数值,否则我会使用 go 来显示所选数字的 static 并强制使用向上/向下按钮。 你可以让它看起来像一个组合锁,如果当前选择的值的总和小于可用的数量,它只允许向上/向下选择。 当然,您需要更新代码以验证没有超过最大值。 禁止用户直接输入将省去验证是否只输入数值的麻烦。
Bod + [0] =
Evasion + [0] -
Masking + [0] -
Sensor + [0] -
Total 0
Maximum ?
您还想考虑使用 CSS 类进行样式设置,而不是直接在标记中指定宽度。 使用 CSS 将帮助您在整个应用程序中保持一致的外观和感觉,并允许您稍后通过(大部分)更改 CSS 而不是应用程序代码本身快速轻松地更改外观和感觉。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.