zbiorcza odpowiedź, może trochę przerost formy nad treścią, ale jeśli komuś to coś rozjaśni, to warto.
@Rafał: przykład w kodzie
@Johny: podobny problem był już dyskutowany http://4programmers.net/Forum/359592?h=#id359592
Poniżej kod przykładu (brak klas .Designer.cs, ale to chyba każdy jest w stanie odtworzyć - pierwsza formatka to textbox i 3 przyciski, druga - textbox i 1 przycisk).
namespace _p_108242
{
// deklaracja delegata aktualizującego wartość z innego wątku
public delegate void SetIntValueDelegate(int value);
public partial class Form1 : Form
{
// prywatna składowa
private int intValue;
// @Rafał: przykład właściwości
public int IntValue
{
get { return intValue; }
set
{
intValue = value;
txtIntValue.Text = intValue.ToString();
}
}
public Form1()
{
InitializeComponent();
// w pasku tytułowym będziemy mieli info o wątku okna
this.Text = string.Format("Thread ID: {0} ; hashcode: {1}",
Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.GetHashCode());
IntValue = 1;
}
private void btnChangeByProperty_Click(object sender, EventArgs e)
{
// obsługa kliknięcia - zmiana z poziomu tego samego wątku
// nie dostaniemy wyjątku, bo obie formatki działają w tym samym wątku
new Form2(this, null).ShowDialog();
}
private void btnChangeByThread_Click(object sender, EventArgs e)
{
// obsługa kliknięcia - zmiana spod innego wątku, bez Invoke
new Thread(new ThreadStart(LaunchThreadChange)).Start();
}
private void btnChangeByThreadInvoke_Click(object sender, EventArgs e)
{
// obsługa kliknięcia - zmiana spod innego wątku, poprzez Invoke
new Thread(new ThreadStart(LaunchThreadChangeInvoke)).Start();
}
private void LaunchThreadChange()
{
btnChangeByProperty_Click(null, null);
// przy aktualizacji z formatki dostaniemy wyjątek
}
private void LaunchThreadChangeInvoke()
{
new Form2(this, new SetIntValueDelegate(SetIntValue)).ShowDialog();
// tu nie będzie wyjatku, bo robimy aktualizację przez Control.Invoke()
}
// metoda aktualizująca dla delegata
private void SetIntValue(int value)
{
IntValue = value;
}
}
}
namespace _p_108242
{
public partial class Form2 : Form
{
private Form1 parent = null;
SetIntValueDelegate setter = null;
public Form2(Form1 parentForm, SetIntValueDelegate setterDelegate)
{
InitializeComponent();
// w pasku tytułowym będziemy mieli info o wątku okna
this.Text = string.Format("Thread ID: {0} ; hashcode: {1}",
Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.GetHashCode());
// referencja do formatki-rodzica
parent = parentForm;
setter = setterDelegate;
txtUpdate.Text = parent.IntValue.ToString();
}
private void btnUpdate_Click(object sender, EventArgs e)
{
if (setter == null)
parent.IntValue = Int16.Parse(txtUpdate.Text);
else
parent.Invoke(setter, new object[1] {Int16.Parse(txtUpdate.Text)} );
Close();
}
}
}