Windows Mobile: изменяем свойства элементов управления из другого потока
Windows Mobile приложение, задача - обновить свойство элемента управления из другого потока.
Итак, создаем новую форму и в событии Form_Load запускаем новый поток, который должен обновить кнопку button1:
public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { Thread t = new Thread(new ThreadStart(Start)); t.Start(); } private void UpdateText() { button1.Text = "New Text"; } void Start() { UpdateText(); } }
Как известно, нельзя получить доступ к элементам управления, которые были созданы в другом потоке. Запустив приложение, мы получим прогнозируемую ошибку:
NotSupportedException: Control.Invoke must be used to interact with controls created on a separate thread.
Также известно, что необходимо использовать делегат в таких случаях:
private delegate void MyDelegate();
И потом использовать такой код:
private void UpdateText() { if (button1.InvokeRequired) { button1.Invoke(new MyDelegate(UpdateText)); } button1.Text = "New Text"; }
Не знаю, почему, но после обновления свойства Text у button1 приложение выдает все ту же ошибку .
После нескольких экспериментов было обнаружено решение под названием "анонимный делегат". Все, что нам нужно - заключить нужный код в анонимный делегат, который без исключения обновит свойство кнопки:
void Start()
{
this.Invoke((MyDelegate)delegate
{
UpdateText();
});
}
Лишний код из метода UpdateText также можно убрать:
private void UpdateText() { button1.Text = "New Text"; }
Happy codding!
Update 1. Обсуждение проблемы на SO.
Update 2. Описаная методика может использоваться и в Windows приложениях.