【问题标题】:C# clickable gridC# 可点击网格
【发布时间】:2012-09-27 12:15:27
【问题描述】:

我正在尝试创建一个具有网格的游戏,用户可以单击网格区域来切换其状态。我正在使用 WinForms。我可以找到两种方法来做到这一点,看起来都很复杂:

  1. 一个表格布局面板,并在每个区域放置一个标签或按钮,当单击该按钮时,找出(以某种方式)单击的列和行并采取相应的行动。
  2. 未绑定的 GridView。

处理这样的事情看起来都非常复杂。

例如,想想井字游戏。在这种情况下,我只需要一个 3x3 网格,并知道单击了哪个区域 (x,y) 并在该区域中绘制一些东西。

【问题讨论】:

标签: c# .net winforms


【解决方案1】:

让我给你看一些我写的更接近你需要的东西,也许:

    private Button button;
    private Dictionary<string, Image> images = new Dictionary<string, Image>();

    public Form1()
    {
        InitializeComponent();
        InitializeTableLayoutPanel();
        AssignClickEvent();

        InitializeDictionary();
    }

    private void Form1_Load(object sender, EventArgs e)
    {

    }

    /// <summary>
    /// Create Buttons for all Cells in the TableLayouPanel
    /// </summary>
    private void InitializeTableLayoutPanel()
    {         
        for (int i = 0; i < tableLayoutPanel.ColumnCount; i++)
        {
            for (int j = 0; j < tableLayoutPanel.RowCount; j++)
            {
                button = new Button();
                button.Visible = true;
                button.Dock = DockStyle.Fill;

                tableLayoutPanel.Controls.Add(button, i, j);
            }
        }
    }

    /// <summary>
    /// Assign a Click event of all Buttons in the TableLayoutPanel
    /// </summary>
    private void AssignClickEvent()
    {
        foreach (Control c in tableLayoutPanel.Controls.OfType<Button>())
        { 
            c.Click += new EventHandler(OnClick);
        }
    }

    /// <summary>
    /// Handle the Click event
    /// </summary>
    /// <param name="sender">Button</param>
    /// <param name="e">Click</param>
    private void OnClick(object sender, EventArgs e)
    {
        Button button = sender as Button;
        button.Visible = false;

        int column = tableLayoutPanel.GetPositionFromControl(button).Column;
        int row = tableLayoutPanel.GetPositionFromControl(button).Row;

        InitializePictureBox(column, row);
    }

    /// <summary>
    /// Create the PictureBox 
    /// </summary>
    /// <param name="column">TableLayoutPanel Column</param>
    /// <param name="row">TableLayoutPanel Row</param>
    private void InitializePictureBox(int column, int row)
    {
        PictureBox box = new PictureBox();
        box.Dock = DockStyle.Fill;

        string key = string.Format("{0}{1}", column.ToString(), row.ToString());

        box.Image = GetImageFromDictionary(key);

        tableLayoutPanel.Controls.Add(box, column, row);           
    }

    /// <summary>
    /// Get an Image from the Dictionary by Key
    /// </summary>
    /// <param name="key">the calling cell by combined column and row</param>
    /// <returns>Image</returns>
    private Image GetImageFromDictionary(string key)
    {
        return images.Where(x => x.Key == key).Select(x => x.Value).Cast<Image>().SingleOrDefault();             
    }

    /// <summary>
    /// Add Bitmaps to the Dictionary
    /// </summary>
    private void InitializeDictionary()
    {
        string key = string.Empty;
        for (int i = 0; i < tableLayoutPanel.ColumnCount; i++)
        {
            for (int j = 0; j < tableLayoutPanel.RowCount; j++)
            {
                key = string.Format("{0}", i.ToString() + j.ToString());
                Image image = CreateBitmap();
                images.Add(key, image);
            }
        }
    }

    /// <summary>
    /// Create Bitmaps for the Dictionary
    /// </summary>
    /// <returns>Bitmap</returns>
    private Bitmap CreateBitmap()
    {
        System.Drawing.Bitmap image = new Bitmap(button.Width, button.Height);
        for (int x = 0; x < image.Width; x++)
        {
            for (int y = 0; y < image.Height; y++)
            {
                image.SetPixel(x, y, Color.Red);
            }
        }
        return image;
    }

点击前:

点击后:

请注意,我已经通过设计器创建了列和行,但我认为以编程方式创建它们并没有什么特别之处。

下一步可能是什么?

  1. 制作各种彩色图片
  2. 以编程方式创建面板的列和行
  3. 通过设置单独的设置使其更灵活

希望这会有所帮助。

【讨论】:

  • 我最终做了类似的事情。
【解决方案2】:

使用 PictureBox 并自己绘制网格线。例如,您可以通过注册事件 Paint 来做到这一点。然后注册事件MouseClick 以获取用户单击网格(在图片框上)的位置和详细信息。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-12-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-18
    • 2015-03-04
    相关资源
    最近更新 更多