Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 09.01.2012, 01:42   #1
GregRUS
 
Регистрация: 02.01.2012
Сообщений: 5
Сообщение [C#] Изменение текста label1 из другого потока/класса

Доброе время суток!

В проекте Visual Studio 2010 столкнулся с проблемой доступа к элементам controls основной формы из методов других классов.
Чтобы не нагружать ненужной информацией - просто приведу суть на основе нового проекта.

Есть форма:


Код:
Код:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Forms;

namespace TestForm1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Form2 myform2 = new Form2();
            Thread t = new Thread(myform2.ThreadProc);
            t.IsBackground = true;
            t.Start();
        }
    }
    public class Form2 : Form1 // Наследуем из 1й формы
    {
        public void ThreadProc()
        {
            label1.Text = "New label1 text";
        }
    }
}
Выводит ошибку связанную с доступом...
Error 1 'TestForm1.Form1.label1' is inaccessible due to its protection level

Что в принципе логично... только вот решения найти не могу.
Также в ините первой формы менял: private System.Windows.Forms.Label label1; на public...
В этом случае ошибка пропадает, но изменений никаких не происходит.
Прошу помощи
GregRUS вне форума Ответить с цитированием
Старый 09.01.2012, 03:07   #2
rUs_LAN
Форумчанин
 
Регистрация: 15.11.2008
Сообщений: 577
По умолчанию

так?
Код:
public class Form2 : Form1 // Наследуем из 1й формы
        {
            public void ThreadProc()
            {
                base.label1.Text = "sdfsdf";
                base.ShowDialog();
            }
        }
rUs_LAN вне форума Ответить с цитированием
Старый 09.01.2012, 10:44   #3
GregRUS
 
Регистрация: 02.01.2012
Сообщений: 5
По умолчанию

К сожалению, нет.
В этом случае открывается еще одна копия диалога Form1.



UPD:
В случае с новым классом БЕЗ создания нового потока - помогло:
(Application.OpenForms[0] as Form1).label1.Text = "Test";

В случае же с новым потоком нужно обратиться сюда:
http://msdn.microsoft.com/en-us/library/ms171728.aspx

...буду разбираться.

Последний раз редактировалось GregRUS; 09.01.2012 в 10:58. Причина: UPD
GregRUS вне форума Ответить с цитированием
Старый 11.01.2012, 09:24   #4
KobolD
Форумчанин
 
Регистрация: 10.06.2010
Сообщений: 239
По умолчанию

Попробуй так
Код:
namespace TestForm1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Form2 myform2 = new Form2();
            myform2.Owner = this; // Передаем во вторую форму указатель на первую форму
            Thread t = new Thread(myform2.ThreadProc);
            t.IsBackground = true;
            t.Start();
        }
    }
    public class Form2 : Form1 // Наследуем из 1й формы
    {
        public void ThreadProc()
        {
            string txt ="New label1 text"; //Записываем текст в переменную чтобы проще было его менять, т.к дальше он будет вызываться в двух местах (if/else)
            Form1 frm = (Form1)this.Owner;// Достаем первую форму через указатель

            if (frm.label1.InvokeRequired) //Проверка на инвок
                frm.label1.BeginInvoke(new Action<string>((s) => frm.label1.Text = s), txt);
            else
                frm.label1.Text = txt;

        }
    }
}
Плюс еще можно с помощью делегатов, но использования проверки на invoke обязательно, т.к. ты из другого потока вызываешь.

P.S. Забыл сказать, что надо в Form1.Designer поменять уровень видимости label1 с приватной на публичную ( public System.Windows.Forms.Label label1; )
Если делать через делегаты то уровень видмости можно не менять.
Чтобы слова не расходились с делом, нужно молчать и ничего не делать.

Последний раз редактировалось KobolD; 11.01.2012 в 09:30.
KobolD вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Доступ из другого потока Invoke delias C# (си шарп) 17 06.06.2013 22:33
Конструктор класса не хочет принимать в качестве параметра адрес объекта другого класса Jugger Помощь студентам 3 05.01.2012 04:10
Быстрый вызов метода формы из другого потока Swarog Общие вопросы Delphi 3 21.05.2011 20:34
Доступ из другого класса KipZ Windows Forms 1 06.02.2011 15:22
Если в классе объявить объект другого класса,будет ли видно переменные первого класса из объекта второго? TwiX Общие вопросы Delphi 3 15.11.2009 00:54