All of what I've posted so far goes in the so-called "business layer". I put this in a separate .NET "class library" project. This way, I can use this same code for any sort of visual display - be it on in desktop windows forms application or a simple console app. I stuck all the code in its own namespace as well to differentiate it from any sort of "presentation layer" code that I would happen to write.
Now that I've given you the run-down of all the code that makes this program tick, let me give you a quick example of the presentation-layer code. At the end of the article you can download all the code as one .NET solution.
BoardControl.ascx
- <%@ Control Language="C#" AutoEventWireup="true" Inherits="BoardControl" %>
- <div class="boardControl">
- <asp:ImageButton ID="btnPosition1" runat="server" ImageUrl="~/App_Themes/<%= Page.Theme %>/Images/empty.jpg" CssClass="button" OnClick="btnPosition_Click" />
- <asp:ImageButton ID="btnPosition2" runat="server" ImageUrl="~/App_Themes/<%= Page.Theme %>/Images/empty.jpg" CssClass="button" OnClick="btnPosition_Click" />
- <asp:ImageButton ID="btnPosition3" runat="server" ImageUrl="~/App_Themes/<%= Page.Theme %>/Images/empty.jpg" CssClass="button" OnClick="btnPosition_Click" /><br />
- <asp:ImageButton ID="btnPosition4" runat="server" ImageUrl="~/App_Themes/<%= Page.Theme %>/Images/empty.jpg" CssClass="button" OnClick="btnPosition_Click" />
- <asp:ImageButton ID="btnPosition5" runat="server" ImageUrl="~/App_Themes/<%= Page.Theme %>/Images/empty.jpg" CssClass="button" OnClick="btnPosition_Click" />
- <asp:ImageButton ID="btnPosition6" runat="server" ImageUrl="~/App_Themes/<%= Page.Theme %>/Images/empty.jpg" CssClass="button" OnClick="btnPosition_Click" /><br />
- <asp:ImageButton ID="btnPosition7" runat="server" ImageUrl="~/App_Themes/<%= Page.Theme %>/Images/empty.jpg" CssClass="button" OnClick="btnPosition_Click" />
- <asp:ImageButton ID="btnPosition8" runat="server" ImageUrl="~/App_Themes/<%= Page.Theme %>/Images/empty.jpg" CssClass="button" OnClick="btnPosition_Click" />
- <asp:ImageButton ID="btnPosition9" runat="server" ImageUrl="~/App_Themes/<%= Page.Theme %>/Images/empty.jpg" CssClass="button" OnClick="btnPosition_Click" />
- </div>
This is the markup for the user control. All we have is basically a bunch of buttons (using CSS they float just right so that there are only 3 buttons in one row).
In the code-behind we expose a very important public property called Board. In it we store the current Board object in the ViewState. We can do this because in our Board.cs file I marked the Board class with the [Serializable()] attribute. This is a great boon to us, because we can use the same Board object across page requests.
- /// <summary>
- /// Internal Board object to represent state
- /// </summary>
- public Board Board
- {
- get
- {
- object board = ViewState["_Board"];
- // if board doesn't exist, create new one
- if (board == null)
- {
- ViewState["_Board"] = b;
- return b;
- }
- else
- {
- return (Board)board;
- }
- }
- private set
- {
- ViewState["_Board"] = value;
- }
- }
- /// <summary>
- /// Restore this control from a Board object
- /// </summary>
- /// <param name="board">Board to represent internal state.</param>
- private void RestoreControlFromBoard(Board board)
- {
- int i = 1;
- foreach (BoardPlayer player in board)
- {
- ImageButton btn = (ImageButton) FindControl(string.Format("btnPosition{0}", i));
- btn.ImageUrl = GetImageUrlForPlayer(player);
- // if a player has made a move on this button, disable it, so
- // we can't still click on it
- if (player != BoardPlayer.NoPlayer)
- btn.Enabled = false;
- i++;
- }
- }
- protected void Page_Load(object sender, EventArgs e)
- {
- if (!IsPostBack)
- {
- // Restore the controls on form from the Board object
- RestoreControlFromBoard(Board);
- if (Board.IsEmpty())
- MakeComputerMove(true);
- }
- }
That is all the major portions of the code to review. The rest is straightforward ASP.NET form code for displaying the UserControl we make in our page form. You can see in the solution I provide that I've added some sugar and put our User Control in Microsoft's new UpdatePanel control. That lets us do some fancy AJAX without doing any work at all.
I wish I could provide a working demo, but the way my hosting is set up, I cannot run .NET code without buying a whole new hosting account. Oh well! Hope that helps for now! You can download the full source for this project below. Thanks.
(Notes: Realize that I coded this project for clean-ness and readability. Also modularization and easy modification. That said, the code could be more compact if you wanted it to be, and you could accomplish the same thing with fewer lines of code. However, the price you would pay would be readability and maintenance. I figured it was worth it to Keep It Simple Stupid.)
Downloads
| Filename | Filesize | Date | Link | |
|---|---|---|---|---|
![]() | tictactoe_asp_net.zip | 398K | 2007-11-18 | Download |
Trackback
Trackback URL for Entry: http://www.thehomeofjon.net/trackback/receive/45.htmlLeave a Comment

Page 2 of 2