Windows Forms Menu (XNA Style)

lxXTaCoXxl 0 Tallied Votes 148 Views Share

XNA Game Studio is not required to use this functionality. This example is very basic, and I typed it up because I was bored. It does not contain functionality for navigation through the menu, but it will display the menu as it should at the specified location. Please enjoy it, and I will revise it later tonight when I'm not busy and update this post with a version that supports navigation. Until then, enjoy. :)

Jamie

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace Menu
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        Menu myMenu = new Menu(new Point(15, 15));

        MenuEntry Entry1 = new MenuEntry("Play");
        MenuEntry Entry2 = new MenuEntry("Options");
        MenuEntry Entry3 = new MenuEntry("Credits");
        MenuEntry Entry4 = new MenuEntry("Exit");

        private void Form1_Load(object sender, EventArgs e)
        {
            myMenu.NewMenuItem(Entry1);
            myMenu.NewMenuItem(Entry2);
            myMenu.NewMenuItem(Entry3);
            myMenu.NewMenuItem(Entry4);

            for (int i = 0; i < myMenu.SelectedIndex; i++)
                this.Controls.Add(myMenu.Items[i]);
        }
    }

    public class MenuEntry
    {
        public string Text;
        public Point Location;

        public MenuEntry(string Text)
        {
            this.Text = Text;
        }
    }

    public class Menu
    {
        public List<MenuEntry> MenuItems;
        public Point Location;
        public int SelectedIndex = 0;
        public List<Label> Items;

        public Menu(Point Location)
        {
            MenuItems = new List<MenuEntry>();
            Items = new List<Label>();
            this.Location = Location;
        }

        public void NewMenuItem(MenuEntry Entry)
        {
            MenuItems.Add(new MenuEntry(Entry.Text));
            Items.Add(new Label());

            if (this.SelectedIndex == 0)
                MenuItems[SelectedIndex].Location = this.Location;

            else
                MenuItems[SelectedIndex].Location = new Point(this.Location.X, MenuItems[SelectedIndex - 1].Location.Y + Items[SelectedIndex].Size.Height);

            Items[SelectedIndex].Text = Entry.Text;
            Items[SelectedIndex].Location = MenuItems[SelectedIndex].Location;

            SelectedIndex++;
        }
    }
}
lxXTaCoXxl 26 Posting Whiz in Training

I will add a ton more of functionality to this; things like color, fonts, and other miscelaneous items of normal menus.

lxXTaCoXxl 26 Posting Whiz in Training

***UPDATE***

// v1.2
// I've added colors and fonts to the menu items, as well as set a default value.
// There is only one bug with the update at this time;
// I've set it up so that the font size can be changed,
// But at runtime it's not correctly placing the menu entries;
// I will work on it and get the functionality up to speed.
// Anyways, here is the updated source.
// I've included the empty class template for the event args that will handle the navigation of the menu.
// I'm going to go eat and then get back to work. I haven't eaten anything in about 3 days.
// Loss of appitite.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace Menu
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        Menu myMenu = new Menu(new Point(15, 15));

        MenuEntry Entry1 = new MenuEntry("Play", "OCR A Extended", 10f, FontStyle.Regular, GraphicsUnit.Point, Color.Red);
        MenuEntry Entry2 = new MenuEntry("Options", "OCR A Extended", 10f, FontStyle.Regular, GraphicsUnit.Point, Color.Blue);
        MenuEntry Entry3 = new MenuEntry("Credits", "OCR A Extended", 10f, FontStyle.Regular, GraphicsUnit.Point, Color.Yellow);
        MenuEntry Entry4 = new MenuEntry("Exit", "OCR A Extended", 10f, FontStyle.Regular, GraphicsUnit.Point, Color.Lime);

        private void Form1_Load(object sender, EventArgs e)
        {
            myMenu.NewMenuItem(Entry1);
            myMenu.NewMenuItem(Entry2);
            myMenu.NewMenuItem(Entry3);
            myMenu.NewMenuItem(Entry4);

            for (int i = 0; i < myMenu.SelectedIndex; i++)
                this.Controls.Add(myMenu.Items[i]);
        }
    }

    public class MenuEntry
    {
        public string Text;
        public Point Location;
        public Color Color = Color.Black;
        public Font Font = new Font("OCR A Extended", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));

        public MenuEntry(string Text, string FontName, float FontSize, FontStyle Style, GraphicsUnit GraphicsUnit, Color Color)
        {
            this.Text = Text;
            this.Font = new Font(FontName, FontSize, Style, GraphicsUnit, ((byte)(0)));
            this.Color = Color;
        }
    }

    public class Menu
    {
        private List<MenuEntry> MenuItems;
        public Point Location { get; private set; }
        public int SelectedIndex { get; private set; }
        public List<Label> Items { get; private set; }

        public int SelectedItem { get; private set; }

        public Menu(Point Location)
        {
            MenuItems = new List<MenuEntry>();
            Items = new List<Label>();
            this.Location = Location;
        }

        public void NewMenuItem(MenuEntry Entry)
        {
            MenuItems.Add(Entry);
            Items.Add(new Label());

            if (this.SelectedIndex == 0)
                MenuItems[SelectedIndex].Location = this.Location;

            else
                MenuItems[SelectedIndex].Location = new Point(this.Location.X, MenuItems[SelectedIndex - 1].Location.Y + Items[SelectedIndex].Size.Height);

            Items[SelectedIndex].Text = Entry.Text;
            Items[SelectedIndex].Location = MenuItems[SelectedIndex].Location;
            Items[SelectedIndex].Font = Entry.Font;
            Items[SelectedIndex].ForeColor = Entry.Color;
            Items[SelectedIndex].BackColor = Color.Transparent;

            SelectedIndex++;
        }
    }

    public class Dev9MenuIndexChanged : EventArgs
    {

    }
}
lxXTaCoXxl 26 Posting Whiz in Training

UPDATE: Fixed all problems but one. The application is updating too fast because I'm using a timer so before the class has a chance to fix it's index value (to prevent it from going out of range) it updates and throws the exception. Other than that it works fine. I've now included navigation functionality.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;

namespace Menu
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        Menu myMenu = new Menu(new Point(15, 15));

        MenuEntry Entry1 = new MenuEntry("Play", Color.Red);
        MenuEntry Entry2 = new MenuEntry("Options", Color.Red);
        MenuEntry Entry3 = new MenuEntry("Credits", Color.Red);
        MenuEntry Entry4 = new MenuEntry("Exit", Color.Red);

        private void Form1_Load(object sender, EventArgs e)
        {
            myMenu.AddEntry(Entry1);
            myMenu.AddEntry(Entry2);
            myMenu.AddEntry(Entry3);
            myMenu.AddEntry(Entry4);

            for (int i = 0; i < myMenu.Items.Count; i++)
                this.Controls.Add(myMenu.Items[i]);

            // Timer
            Updater.Start();
        }

        // Timer Tick
        private void UpdateMenu(object sender, EventArgs e)
        {
            myMenu.Update();
        }

        // Form1_KeyDown
        private void NavigateMenu(object sender, KeyEventArgs e)
        {
            myMenu.Navigate(e);
        }
    }

    public class MenuEntry
    {
        public string Text = "";

        public Point Location;
        public Color Color;
        public Font Font = new Font("OCR A Extended", 8.25f, FontStyle.Regular, GraphicsUnit.Point, ((byte)(0)));

        public MenuEntry(string Text)
        {
            this.Text = Text;
            Color = Color.White;
        }

        public MenuEntry(string Text, Color Color)
        {
            this.Text = Text;
            this.Color = Color;
        }

        public MenuEntry(string Text, Font Font, Color Color)
        {
            this.Text = Text;
            this.Font = Font;
            this.Color = Color;
        }

        public MenuEntry(string Text, string FontName, float FontSize, Color Color)
        {
            this.Text = Text;
            this.Font = new Font(FontName, FontSize, FontStyle.Regular, GraphicsUnit.Point, ((byte)(0)));
            this.Color = Color;
        }
    }

    public class Menu
    {
        private Input Input = new Input();
        private List<MenuEntry> MenuItems;

        public List<Label> Items { get; private set; }
        public Point Location { get; private set; }

        public int Length { get; private set; }
        public int SelectedIndex { get; private set; }

        public Color SelectionColor { get; private set; }

        public Menu(Point Location)
        {
            MenuItems = new List<MenuEntry>();

            this.Length = 0;
            this.SelectedIndex = 0;
            this.Location = Location;
            this.SelectionColor = Color.White;

            Items = new List<Label>();
        }

        public Menu(Point Location, Color SelectionColor)
        {
            MenuItems = new List<MenuEntry>();

            this.Length = 0;
            this.SelectedIndex = 0;
            this.Location = Location;
            this.SelectionColor = SelectionColor;

            this.Items = new List<Label>();
        }

        public void AddEntry(MenuEntry Entry)
        {
            MenuItems.Add(Entry);
            Items.Add(new Label());

            if (this.Length == 0)
                MenuItems[Length].Location = this.Location;

            else
                MenuItems[Length].Location = new Point(this.Location.X, MenuItems[Length - 1].Location.Y + Items[Length - 1].Size.Height + 5);

            Items[Length].BackColor = Color.Transparent;
            Items[Length].Text = Entry.Text;
            Items[Length].Font = Entry.Font;
            Items[Length].ForeColor = Entry.Color;
            Items[Length].Location = MenuItems[Length].Location;

            Length++;
        }

        public void Navigate(KeyEventArgs e)
        {
            if (Input.NavigatingUp(e))
            {
                if (SelectedIndex <= 0)
                    SelectedIndex = MenuItems.Count;

                else
                    SelectedIndex--;
            }

            else if (Input.NavigatingDown(e))
            {
                if (SelectedIndex >= MenuItems.Count)
                    SelectedIndex = 0;

                else
                    SelectedIndex++;
            }
        }

        public void Update()
        {
            for (int i = 0; i < Items.Count; i++)
                Items[i].ForeColor = MenuItems[i].Color;

            Items[SelectedIndex].ForeColor = this.SelectionColor;
        }
    }

    public class Input
    {
        private bool Up = false;
        private bool Down = false;

        public bool NavigatingUp(KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Up)
            {
                Up = true;
                Thread.Sleep(10);
            }

            else
                Up = false;

            return Up;
        }

        public bool NavigatingDown(KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Down)
            {
                Down = true;
                Thread.Sleep(10);
            }

            else
                Down = false;

            return Down;
        }
    }
}
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.