Diskuze: Přístup k formuláři z jiné třídy a vlákna
Zobrazeno 2 zpráv z 2.
pokud použiješ komponentu BackgroundWorker tak v obluze jeho události
RunWorkerCompleted můžeš rovnou přidat kontrolky na formulář bez použití
Invoke,
nebo použít Invoke pokud chceš ovládat form z jiného vlákna,
nebo využít SynchronizationContext a metodu Post a pak už nemusíš řešit
Invoke
Tupej příklad jak by to šlo udělat, ale osobně bych to řešil přes vzor MVP-Passive View
formulář Form1:
public partial class Form1:Form
{
private Searcher searcher;
public Form1()
{
InitializeComponent();
searcher = new Searcher();
searcher.Searched += new EventHandler<Searcher.ResultEventArgs>(searcher_Searched);
}
void searcher_Searched(object sender, Searcher.ResultEventArgs e)
{
if(this.InvokeRequired)
this.Invoke((MethodInvoker)(()=>{createControls(e)}));
else
createControls(e);
}
createControls(Searcher.ResultEventArgs e)
{
Label label = new Label();
label.Text = e.LabelText;
label.Location=new Point(10,20);
//.....
this.Controls.Add(label);
}
}
a v konstruktoru formuláře zaregistrovat dokončené hledání
searcher.Searched
v obsluze události formuláře Shown spustit
class Searcher
{
public class ResultEventArgs : EventArgs
{
public string LabelText;
public string PicturePath;
}
public event EventHandler<ResultEventArgs> Searched = delegate{};
private Thread serachingThread = null;
private object _lock = new object();
public void StartSearchingAsync()
{
lock(_lock)
{
if(serachingThread != null)
return;
serachingThread = new Thread(doSearch)
serachingThread.Start();
}
}
private void doSearch()
{
while(true)
{
if(podminkaSplnena)
{
ResultEventArgs res = getSomeData(); //naplnit potřebná data
Searched(this, res);
}
Thread.Sleeep(10); //čekat aspoň 10ms pokud by došlo k rychlému cyklení
}
}
}
Zobrazeno 2 zpráv z 2.