@bLercs

Как создать ui панельку в ответ на подключение пользователя?

Вопрос скорее архитектурный.
Есть сервер(TcpListener), который в отдельном потоке принимает подключения. При подключении нового пользователя, в главной форме должна создаваться панелька с некоторыми контроллерами. Но есть проблема, создать элемент правления в форме нельзя из другого потока. Как это разрешить?

Пробовал Invoke, вылезает проблема для отдельного вопроса о синхронизации общих блоков памяти для различных потоков.

Контроллер сцен:
пока затупил на первой
public GameMaster(ref Form mainform)
        {
            this.mainform = mainform;
            clients = new List<ConnectedEntity>();
            components = new List<IBaseScene>
            {
                new NetBehaviourScene(CreateEntity)
            };


        }

        void CreateEntity(TcpClient tcpclient)
        {
            ConnectedEntity client = new ConnectedEntity(ref mainform, ref tcpclient);
            clients.Add(client);
        }


Класс, хранящий поток клиента и его панельку:
public ConnectedEntity(ref Form mainform, ref TcpClient client)
        {
            this.client = client;
            //int.Parse(Read().Substring(6, 1)) - seatID, который присылает клиент при подключении
            gui = new Pretender(int.Parse(Read().Substring(6, 1)), ref mainform, (object sender, EventArgs e) => { 
                isCookieEaten = !isCookieEaten;
            });
        }


Сервер:
public FFServer(ref bool isConnectionAllowed, Action<TcpClient> ConnectedCallback)
        {
            port = 9850;
            this.isConnectionAllowed = isConnectionAllowed;
            this.ConnectedCallback = ConnectedCallback;
            listener = new TcpListener(IPAddress.Any, port);
        }

public void Update()
        {
            if (isConnectionAllowed)
            {
                listener.BeginAcceptTcpClient((IAsyncResult ar) =>
                {
                    ConnectedCallback(listener.EndAcceptTcpClient(ar));
                }, listener);
            }
        }


Создание панельки:
public Pretender(int seatID, ref Form mainform, Action<object, EventArgs> CookieCheckCallback)
        {
            this.mainform = mainform;
            //точка первой панель относительно основной формы
            panelStartPoint = new System.Drawing.Point(341, 12);

            //расчёт окончательной точки панели (нечётные слева, чётные справа)
            if (seatID % 2 != 0)
            {
                panelStartPoint = new System.Drawing.Point(panelStartPoint.X,
                    panelStartPoint.Y + yPanelOffset * (seatID / 2));
            } else
            {
                panelStartPoint = new System.Drawing.Point(panelStartPoint.X + xPanelOffset,
                    panelStartPoint.Y + yPanelOffset * (seatID / 2));
            }

            this.pPretender = new System.Windows.Forms.Panel();
            this.cbIsInGame = new System.Windows.Forms.CheckBox();
            this.cbEatCookie = new System.Windows.Forms.CheckBox();
            this.lSeatID = new System.Windows.Forms.Label();
            this.lAnswer = new System.Windows.Forms.Label();
            this.tbPretenderName = new System.Windows.Forms.TextBox();
            pPretender.SuspendLayout();

            this.lAnswer.AutoSize = true;
            this.lAnswer.Location = new System.Drawing.Point(70, 159);
            this.lAnswer.Name = "lAnswer";
            this.lAnswer.Size = new System.Drawing.Size(18, 20);
            this.lAnswer.TabIndex = 2;
            this.lAnswer.Text = "?";

            this.tbPretenderName.Location = new System.Drawing.Point(3, 32);
            this.tbPretenderName.Name = "tbPlayerName";
            this.tbPretenderName.Size = new System.Drawing.Size(271, 26);

            this.lSeatID.AutoSize = true;
            this.lSeatID.Location = new System.Drawing.Point(70, 96);
            this.lSeatID.Name = "lSeatID";
            this.lSeatID.Size = new System.Drawing.Size(18, 20);
            this.lSeatID.Text = seatID.ToString();

            this.cbEatCookie.AutoSize = true;
            this.cbEatCookie.Checked = false;
            this.cbEatCookie.CheckState = System.Windows.Forms.CheckState.Unchecked;
            this.cbEatCookie.Location = new System.Drawing.Point(196, 64);
            this.cbEatCookie.Name = "cbEatCookie";
            this.cbEatCookie.Size = new System.Drawing.Size(77, 24);
            this.cbEatCookie.Text = "Печенька";
            this.cbEatCookie.UseVisualStyleBackColor = true;
            this.cbEatCookie.Enabled = false;
            this.cbEatCookie.CheckedChanged += new System.EventHandler(CookieCheckCallback);

            this.cbIsInGame.AutoSize = true;
            this.cbIsInGame.Checked = true;
            this.cbIsInGame.CheckState = System.Windows.Forms.CheckState.Checked;
            this.cbIsInGame.Location = new System.Drawing.Point(7, 64);
            this.cbIsInGame.Name = "cbIsInGame";
            this.cbIsInGame.Size = new System.Drawing.Size(77, 24);
            this.cbIsInGame.Text = "В игре";
            this.cbIsInGame.UseVisualStyleBackColor = true;
            this.cbIsInGame.CheckedChanged += new System.EventHandler(this.cbIsInGame_CheckedChanged);
            
            this.pPretender.Controls.Add(this.cbIsInGame);
            this.pPretender.Controls.Add(this.cbEatCookie);
            this.pPretender.Controls.Add(this.lSeatID);
            this.pPretender.Controls.Add(this.lAnswer);
            this.pPretender.Location = panelStartPoint;
            this.pPretender.Name = "pPretender";
            this.pPretender.Size = new System.Drawing.Size(277, 160);
            this.pPretender.TabIndex = 2;

            //Добавление панельки  в основную форму
            mainform.Controls.Add(pPretender);
        }
  • Вопрос задан
  • 74 просмотра
Решения вопроса 1
petermzg
@petermzg
Самый лучший программист
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы