I'm calling a method in a different class, how do I reference the form?

  • Thread starter Thread starter DrPete
  • Start date Start date
D

DrPete

To tidy up my code, within a form I am calling a method in a different
class, e.g.

switch (listBox1.SelectedItems.ToString())
{
case "Stock":
Stock.doMigrate();
break;
default:
break;
}

Within the Stock.doMigrate code how do I reference any of the
components on the form? I can't seem to figure it out nor find
examples on the web.. Your help would greatly be appreciated!

Peter
 
At the simplest level: you can't.

Technically (not recommended) you could pass the form-reference as a
parameter into the doMigrate method (i.e. doMigrate(this);) - however, you
are then tightly coupling the UI and your underlying business processes. The
much better option is to figure out what information is needed, and make
that available (independent of how it is represented in the UI) to the Stock
class; this could be via method parameters, or could be via properties.
Another option (if there are LOTS of parameters) would be to make your form
implement a custom interface, that abstracts "what is required" from "how it
is displayed" - you would then pass the form as a parameter, and let it do
its thing. This is preferable to the method accepting a "Form" object, but I
still prefer divorcing the two completely.

Marc
 
Marc

I have a question that is along this same thought thread: I would like a
supporting method (In a separate class from my GUI {form}) send completion
data to a progressbar. I have decided to put this rather lengthy method in
the Forms class since it seems incapable of residing in a class of its own.
I would like to "black Box" this so I could design it once and use it
forever. I have used it several times but always cutting and pasting it to
the GUI.

Also in your response to drpete you were a little over my head. Please
speak slowly, I’m an old dog, I’ll get it but a little visual is worth a
thousand words.

Thanks in advance
 
"black box" and re-use is exactly what my previous post was driving at;
really, in order to talk happily to multiple (disparate) UIs, it is best to
follow the eventing model. The following illustrates this using a summy
worker; note that you could also use the BackgroundWorker for some of this,
but this then necessitates your worker class integrating with the worker
directly, which is a pain. Anyways, code follows; note it demonstrates sync
and async, using the ISynchronizeInvoke interface so that the worker can
liaise with the UI thread (using BeginInvoke since we don't need any return
data; if this was a CancelEventArgs-style handler, then you would Invoke so
that you wait for the updated values).


using System;
using System.Windows.Forms;
using System.ComponentModel;
using System.Threading;
using System.Diagnostics;

static class Program {
static void Main() {
using (MyForm form = new MyForm()) {
form.ShowDialog();
}
}
}
class MyForm :Form {
Button sync, async;
ProgressBar bar;
public MyForm() {
bar = new ProgressBar();
bar.Dock = DockStyle.Bottom;
bar.Minimum = 0; bar.Maximum = 100; bar.Style =
ProgressBarStyle.Continuous;
sync = new Button(); sync.Dock = DockStyle.Left; sync.Text = "Sync";
async = new Button(); async.Dock = DockStyle.Right; async.Text =
"Async";
Controls.Add(sync); Controls.Add(async); Controls.Add(bar);
sync.Click += delegate {
MyWorker worker = new MyWorker();
worker.ProgressChanged += UpdateProgress;
worker.DoWork();
};
async.Click += delegate {
MyWorker worker = new MyWorker(this);
worker.ProgressChanged += UpdateProgress;
ThreadPool.QueueUserWorkItem((WaitCallback)delegate {
worker.DoWork();
});
};
}
void UpdateProgress(object sender, ProgressChangedEventArgs args) {
sync.Enabled = async.Enabled = (args.Percent == 100);
bar.Value = args.Percent;
}

}

class ProgressChangedEventArgs : EventArgs {
public readonly int Percent;
public ProgressChangedEventArgs(int percent) {Percent = percent;}
}
delegate void ProgressChangeEventHandler(object sender,
ProgressChangedEventArgs args);
class MyWorker {
readonly ISynchronizeInvoke _threadingMaster;
public MyWorker() :this (null) { }
public MyWorker(ISynchronizeInvoke threadingMaster) {
_threadingMaster = threadingMaster;
}
public void DoWork() {
Random rand = new Random();
for(int i = 0; i<=100;i++) {
Debug.WriteLine(i);
Thread.Sleep(rand.Next(50));
OnProgressChanged(i);
}
}
public event ProgressChangeEventHandler ProgressChanged;
protected void OnProgressChanged(int percent) {
ProgressChangeEventHandler handler = ProgressChanged;
if (handler == null) return;
ProgressChangedEventArgs args = new
ProgressChangedEventArgs(percent);
if (_threadingMaster != null && _threadingMaster.InvokeRequired) {
_threadingMaster.BeginInvoke(handler, new object[] { this,
args });
} else {
handler(this, args);
}
}
}
 
Back
Top