簡體   English   中英

asp.net 3.5 我“得到”這個了嗎?

[英]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 mvcfubu 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM