Home>

Currently, Sudoku is created with VB.NET.

Click here for the actual game screen.
A Picturebox is placed on the Form and a table is created using Graphics.

The cell is highlighted in orange because of the MauseMove event.

I am worried about the process of inputting characters to the cells in the picturebox.
That is,
1. Specify coordinates with the mouse
2. Receive input key information
3. Output the input key information to the target coordinates (orange frame cell)

For output,
I think that it can be realized by using the Graphics.DrawString method orTextRenderer.DrawText method, but I think that the coordinates are not specified correctly.

This is a Form1 class.

Public Class Form1
    Dim S As New source
    Private Sub PictureBox1_Paint (ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles PictureBox1.Paint
        S.Draw (e.Graphics)
    End Sub
    Private Sub PictureBox1_MouseMove (ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseMove
        Dim ThisCell As Cell
        'Get the cell where the mouse is
        ThisCell = S.CellFromPoint (e.X, e.Y)
        If Not IsNothing (ThisCell) Then
            ThisCell.Focus ()
            Console.ReadLine ()
            'Draw the current state (generates a PaintBox1 Paint event)
            PictureBox1.Invalidate () '← All actual drawing is done here
        End If
    End Sub
End Class
Public Class Cell
    Public Status As CellStatus
    Public S As source
    Public Position As Point 'Logical position
    Public Rectangle As Rectangle 'physical position
    Public Focused As Boolean
    '■ Constructor
    Public Sub New (ByVal S As source, ByVal Position As Point)
        Me.S = S
        Me.Position = Position
        Dim Rect As New Rectangle
        'Find the physical position.
        Rect.X = Position.X * source.CellSize
        Rect.Y = Position.Y * source.CellSize
        Rect.Width = source.CellSizeRect.Height = source.CellSize
        Me.Rectangle = Rect
    End Sub
    '■ Focus
    Public Sub Focus ()
        Dim X As Integer
        Dim Y As Integer
        'Deactivate all other cells belonging to the same grid.
        For X = 0 To source.XCount-1
            For Y = 0 To source.YCount-1
                S.Cells (X, Y) .Focused = False
            Next
        Next
        'Activate yourself.
        Me.Focused = True
    End Sub
    Public Sub Draw (ByVal g As Graphics)
        Dim CellRect As Rectangle
        Dim oPen As New Pen (Color.Orange, 3)
        CellRect = Me.Rectangle
        CellRect.Inflate (-2, -2)
        Dim fnt As New Font ("MS UI Gothic", 20)
        If Me.Focused Then
            g.DrawRectangle (oPen, CellRect)
        End If
    End Sub
End Class
Public Class source
    Public Const CellSize As Integer = 50 'Cell size
    Public Const XCount As Integer = 9 'Number of horizontal cells on the board
    Public Const YCount As Integer = 9 'Number of cells in the vertical direction of the board
    Dim aCell (XCount-1, YCount-1) As Cell 'Array representing all cells
    Public Sub New ()
        Dim X As Integer
        Dim Y As Integer
        For X = 0 To XCount-1
            For Y = 0 To YCount-1
                aCell (X, Y) = New Cell (Me, New Point (X, Y))
            Next
        Next
    End Sub
    Public Sub Draw (ByVal g As Graphics)
        Dim X As Integer
        Dim Y As Integer
        Dim aPen As New Pen (Color.Gray, 2)Dim bPen As New Pen (Color.Black, 3)
        'Rectangle
        g.FillRectangle (Brushes.White, 0, 0, XCount * CellSize, YCount * CellSize)
        'Vertical line
        For X = 0 To XCount
            If X Mod 3 = 0 Then
                g.DrawLine (bPen, X * CellSize, 0, X * CellSize, YCount * CellSize)
            Else
                g.DrawLine (aPen, X * CellSize, 0, X * CellSize, YCount * CellSize)
            End If
        Next
        'horizontal line
        For Y = 0 To YCount
            If Y Mod 3 = 0 Then
                g.DrawLine (bPen, 0, Y * CellSize, XCount * CellSize, Y * CellSize)
            Else
                g.DrawLine (aPen, 0, Y * CellSize, XCount * CellSize, Y * CellSize)
            End If
        Next
        For Y = 0 To YCount-1
            For X = -0 To XCount-1
                Cells (X, Y) .Draw (g)
            Next
        Next
    End Sub
    Public Property Cells (ByVal X As Integer, ByVal Y As Integer) As Cell
        Get
            Return aCell (X, Y)
        End Get
        Set (ByVal value As Cell)
            aCell (X, Y) = value
        End Set
    End Property
    Public Function CellFromPoint (ByVal X As Integer, ByVal Y As Integer) As Cell
        Dim ThisCell As Cell
        If X<0 OrElse X>= XCount * CellSize Then
            Return Nothing
        End If
        If Y<0 OrElse Y>= YCount * CellSize Then
            Return Nothing
        End If
        ThisCell = Cells (X \ CellSize, Y \ CellSize)
        Return ThisCell
    End Function
End Class
  • Answer # 1

    In essence, do you want to receive a keyed value?
    When you say "Enter a string in the table", the story gets complicated.
    Since it is a Sudoku, you just need to be able to enter keys 1-9 (+ Delete key).
    If you use the KeyPress or KeyDown event, you can receive one event per keystroke.
    You can set an event for a specific control, but this type of app is convenient when you receive it in a form (because an event occurs regardless of which control is active)
    In that case, you just need to set the form's KeyPreview property to True.
    Refer here and here. .