I try to create a sudoku resolver. So, in the business logic, we have a game board representing the sudoku. In the business logic, we use a method that does a backtracking processing to resolve Sudoku.
I have the following error with this line in NotifyChange method in Form1.cs : tableLayoutPanel1.Controls.Add(label, column, line);
Inter-thread operation no valid control accessed from a thread other than the thread it was created
SudokuListener.cs :
interface SudokuListener
{
void NotifyChange(Int32 line, Int32 column, Token token);
}
Form1 :
public partial class Form1 : Form, SudokuListener
{
delegate void Del(SudokuListener sudokuListener);
void SudokuListener.NotifyChange(int line, int column, Token token)
{
Label label = new Label();
if (token.IsMarked())
{
label.ForeColor = Color.Blue;
}
label.Text = ""+token.GetNbr();
tableLayoutPanel1.Controls.Add(label, column, line);
}
private void Form1_Load(object sender, EventArgs e)
{
Del del = new Del(SudokuThread.Start);
BackgroundWorker backgroundWorker = new BackgroundWorker();
backgroundWorker.WorkerReportsProgress = true;
backgroundWorker.WorkerSupportsCancellation = true;
backgroundWorker.DoWork += new DoWorkEventHandler(brol);
backgroundWorker.RunWorkerAsync();
}
private void brol(object sender, DoWorkEventArgs e)
{
SudokuThread.Start(this);
}
}
SudokuThread.cs :
class SudokuThread
{
public static void Start(SudokuListener listener)
{
SudokuGameBoard sudokuGameBoard = new SudokuGameBoard();
Sudoku sudoku = new Sudoku();
sudokuGameBoard.AddListeners(listener);
sudoku.Load(sudokuGameBoard);
sudoku.FindSolution(sudokuGameBoard, 0);
}
}
Sudoku.cs :
class Sudoku
{
public void Load(SudokuGameBoard gameBoard)
{
gameBoard.SetToken(0, 0, new Token(0, false));
gameBoard.SetToken(0, 1, new Token(0, false));
gameBoard.SetToken(0, 2, new Token(0, false));
gameBoard.SetToken(0, 3, new Token(0, false));
gameBoard.SetToken(0, 4, new Token(0, false));
gameBoard.SetToken(0, 5, new Token(0, false));
gameBoard.SetToken(0, 6, new Token(0, false));
gameBoard.SetToken(0, 7, new Token(0, false));
gameBoard.SetToken(0, 8, new Token(0, false));
gameBoard.SetToken(1, 0, new Token(0, false));
gameBoard.SetToken(1, 1, new Token(0, false));
gameBoard.SetToken(1, 2, new Token(7, true));
gameBoard.SetToken(1, 3, new Token(8, true));
//rest of the code
}
private void PutToken(SudokuGameBoard gameBoard, Int32 line, Int32 column, Token token)
{
if ( !gameBoard.GetToken(line,column).IsMarked())
{
gameBoard.SetToken(line, column, token);
}
}
public Boolean FindSolution(SudokuGameBoard gameBoard, Int32 position)
{
Boolean finish = false;
Int32 currentNbr = 0;
do {
currentNbr++;
if ( IsPossible(gameBoard, position / 9, position % 9, currentNbr) )
{
PutToken(gameBoard, position / 9, position % 9, new Token(currentNbr));
//rest of the code
}
}while (currentNbr != 9 && !finish);
}
}
SudokuGameBoard.cs :
class SudokuGameBoard
{
public void SetToken(Int32 line, Int32 column, Token newToken)
{
array[line, column] = newToken;
NotifyListeners(line, column, newToken);
}
private void NotifyListeners(Int32 line, Int32 column, Token token)
{
for (Int32 i = 0; i < listeners.Count; i++)
{
listeners[i].NotifyChange(line, column, token);
}
}
}