如何使用winforms在vb.net中创建一个大的按钮网格(24x20或类似的)?

如何使用winforms在vb.net中创建一个大的按钮网格(24x20或类似的)?,vb.net,winforms,button,user-controls,Vb.net,Winforms,Button,User Controls,我正在用vb.net WinForms制作一个座位预订系统,我需要用户能够选择他们想要使用的座位,并让它改变颜色,这样他们就可以知道它被选中了 我开始尝试使用按钮,但480个按钮严重减慢了表单的加载时间。然后我尝试了一个在行/列中带有按钮的数据网格视图,但无法正常工作 我的问题是,我该怎么做 是否值得尝试使用480个图片框并更改其背景颜色?或者这会不会像480个按钮一样让表单变慢?试试这个: private void Form1_Load(object sender, EventArgs e)

我正在用vb.net WinForms制作一个座位预订系统,我需要用户能够选择他们想要使用的座位,并让它改变颜色,这样他们就可以知道它被选中了

我开始尝试使用按钮,但480个按钮严重减慢了表单的加载时间。然后我尝试了一个在行/列中带有按钮的数据网格视图,但无法正常工作

我的问题是,我该怎么做

是否值得尝试使用480个图片框并更改其背景颜色?或者这会不会像480个按钮一样让表单变慢?

试试这个:

 private void Form1_Load(object sender, EventArgs e)
        {
            int index;
            Button[] b=new Button[500];
            for(int i=0;i<24;i++)
            for(int j=0;j<20;j++)
            {
                index = (20 * i) + j;
                b[index]=new Button();
                b[index].Text=index.ToString();
                b[index].Location=new Point(j*80,i*30);
                panel1.Controls.Add(b[index]);
                b[index].Click += new EventHandler(ButtonLeft_Click);    
             }

            }

        private void ButtonLeft_Click(object sender, EventArgs e)
        {
            Button b = (Button)sender;
            if (b.BackColor == Color.Black)
                b.BackColor = Color.White;
            else
                b.BackColor = Color.Black;

              //DB Commands here    
        }

为了提高效率,您并不是真的想要创建大量这样的控件。最好是创建一个自定义控件,在它自己的单个绘图表面上绘制所有座位。下面是一个非常简单的示例:

Public Class SeatingPlan
    Public Class Seat
        Public Rectangle As Rectangle
        Public Selected As Boolean
        Public Id As String

        Public Sub New(ByVal seatId As String, ByVal x As Integer, ByVal y As Integer, ByVal width As Integer, ByVal height As Integer)
            Id = seatId
            Rectangle = New Rectangle(x, y, width, height)
        End Sub
    End Class


    Public ReadOnly Property Seats() As List(Of Seat)
        Get
            Return _seats
        End Get
    End Property
    Private _seats As List(Of Seat) = New List(Of Seat)()


    Public Event SelectedSeatsChanged()


    Private Sub SeatingPlan_MouseClick(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseClick
        For Each seat As Seat In _seats
            If seat.Rectangle.Contains(e.Location) Then
                seat.Selected = Not seat.Selected
                RaiseEvent SelectedSeatsChanged()
                Exit For
            End If
        Next
        Invalidate()
    End Sub


    Private Sub SeatingPlan_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
        For Each seat As Seat In _seats
            Dim seatBackColor As Color = BackColor
            Dim textColor As Color = ForeColor
            If seat.Selected Then
                seatBackColor = Color.FromKnownColor(KnownColor.Highlight)
                textColor = Color.FromKnownColor(KnownColor.HighlightText)
            End If
            e.Graphics.FillRectangle(New SolidBrush(seatBackColor), seat.Rectangle)
            e.Graphics.DrawRectangle(New Pen(ForeColor), seat.Rectangle)
            Dim textSize As SizeF = e.Graphics.MeasureString(seat.Id, Me.Font, seat.Rectangle.Width)
            e.Graphics.DrawString(seat.Id, Font, New SolidBrush(textColor), seat.Rectangle.X + ((seat.Rectangle.Width - textSize.Width) / 2), seat.Rectangle.Y + ((seat.Rectangle.Height - textSize.Height) / 2))
        Next
    End Sub


    Public Function GetSelectedSeatIds() As List(Of String)
        Dim ids As List(Of String) = New List(Of String)()
        For Each seat As Seat In _seats
            If seat.Selected Then
                ids.Add(seat.Id)
            End If
        Next
        Return ids
    End Function


    Public Sub SetSelectedSeatIds(ids As List(Of String))
        For Each seat As Seat In _seats
            seat.Selected = ids.Contains(seat.Id)
        Next
        RaiseEvent SelectedSeatsChanged()
    End Sub
End Class
然后,在表单中,输入如下代码以创建座椅的位置:

Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    SeatingPlan1.Seats.Add(New SeatingPlan.Seat("1A", 3, 3, 20, 20))
    SeatingPlan1.Seats.Add(New SeatingPlan.Seat("2A", 26, 3, 20, 20))
    SeatingPlan1.Seats.Add(New SeatingPlan.Seat("1B", 3, 26, 20, 20))
    SeatingPlan1.Seats.Add(New SeatingPlan.Seat("2B", 26, 26, 20, 20))
End Sub


Private Sub SeatingPlan1_SelectedSeatsChanged() Handles SeatingPlan1.SelectedSeatsChanged
    For Each seatId As String In SeatingPlan1.GetSelectedSeatIds
        'Do something
    Next
End Sub

你需要弄清楚这是一个WinForms应用程序。也许是一个按钮数据网格?我想这也可以解决绑定数据源后端的问题,其中包含有关自由/保留状态的信息。我尝试过,但无法很好地工作…嗨,John,请尝试动态创建控件。是否可以让用户先选择一个节?比如:A区,然后是座位分配?这将防止用户受到巨大网格的攻击。它没有回答我是如何在winforms中显示24x20网格的,但它可能会有所帮助。这很好,但我希望有24个宽度的通道,12个座位后有一个过道,10个座位后有一个过道。而且,看起来虽然行数是1到20,下一行以10开始?如果我在没有VB标记的C问题上发布VB.NET代码,我会得到多少反对票?右键单击项目并从上下文菜单中选择“添加”>“用户控件”。将其命名为SeatingPlan或任何您喜欢的名称,然后将此代码复制并粘贴到用户控件的代码中。然后构建项目。然后去设计师那里找你的表单,座位计划控件应该显示在工具箱的顶部。谢谢这位朋友,我想这可能对我有用!如何添加索引以便记录所选的座位?我要做的是为座位列表创建一个公共属性。当选择或取消选择座位时,它可能也会引发一个事件,以便在表单更改时通知表单。此外,座位列表可能应该由窗体填充,而不是由控件的Load事件填充。这样,该控件就可以用于不同的座位安排。我该怎么做对不起:/我知道如何定义属性,我知道如何获取单击框的索引,但我不知道如何将其正确输出。。。理想情况下,我想要一个selecteditems属性,比如listbox。。。