0

I am trying to create a form that queries a database. The form has a "Query" button and I would like the query to run every 30 seconds automatically as well. However, when I try to do it I get an error saying an object reference is needed for QueryBtn since it is non-static.

However, due to the nature of the form I can't change the QueryBtn to static without causing other problems. How can I call on the action of QueryBtn_Click every 30 seconds?

namespace ModalityWorklistSCU
 {
public partial class ModalityWorklistSCUExampleForm : Form
 {


 // Here's the 30 second timer

        private static System.Timers.Timer myTimer;
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            myTimer = new System.Timers.Timer();
            myTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
            myTimer.Interval = 30000;
            myTimer.Enabled = true;
            Application.Run(new ModalityWorklistSCUExampleForm());
        }

// This is the form

public ModalityWorklistSCUExampleForm()
    {
        InitializeComponent();
    }

// This defines what happens when the timer elapses. I am trying to call the click event of another button.

    private static void OnTimedEvent(object source, ElapsedEventArgs e)

            {   
            QueryBtn.PerformClick();
            }

// This is a snipet of the event I want to call every 5 seconds:

private void QueryBtn_Click(object sender, EventArgs e)
    {
        DCXOBJIterator it = null;
        DCXREQ req = null;
        DCXOBJ rp = null;
        DCXOBJ sps = null;
        DCXELM el = null;
        DCXOBJIterator spsIt = null;
        try
        {
            // Fill the query object
            rp = new DCXOBJ();
            sps = new DCXOBJ();
            el = new DCXELM();

            // Build the Scheduled procedure Step (SPS) item
            el.Init((int)DICOM_TAGS_ENUM.ScheduledStationAETitle);
            el.Value = StationNameEdit.Text;
            sps.insertElement(el);

Thanks

user3067200
  • 21
  • 1
  • 6
  • 2
    Easy, refactor your business logic from your click handler into a separate function and call this function from the handler and from the timer? – whosrdaddy Dec 06 '13 at 07:23
  • 1
    Dont call a click event unless a button is clicked. Pull your code out of your event handler, have the event handler call the new method and also have your timer call the new method. – crthompson Dec 06 '13 at 07:23
  • What's the actual name of your button? – King King Dec 06 '13 at 07:24

2 Answers2

2

Refactor your code to pull logic out of your event handler.

private void QueryBtn_Click(object sender, EventArgs e)
{
    NewMethod();
}
private static void OnTimedEvent(object source, ElapsedEventArgs e)
{   
    NewMethod();
}
private void NewMethod()
{
    DCXOBJIterator it = null;
    DCXREQ req = null;
    DCXOBJ rp = null;
    DCXOBJ sps = null;
    DCXELM el = null;
    DCXOBJIterator spsIt = null;
    try
    {
        // Fill the query object
        rp = new DCXOBJ();
        sps = new DCXOBJ();
        el = new DCXELM();

        // Build the Scheduled procedure Step (SPS) item
        el.Init((int)DICOM_TAGS_ENUM.ScheduledStationAETitle);
        el.Value = StationNameEdit.Text;
        sps.insertElement(el);
    }
}
crthompson
  • 15,653
  • 6
  • 58
  • 80
1

Instead of System.Timers.Timer try to use System.Windows.Forms.Timer.

Here is some info on it:

http://msdn.microsoft.com/en-us/library/system.windows.forms.timer(v=vs.110).aspx

Draw the timer element on the form straight from the form designer, add event handler for Tick event and execute your logic there. You should move all your logic to separate function and call it from button Click event and Timer event.

You can also call button click event handler directly just as any method just passing needed arguments, but as paqogomez correctly pointed out, this is not considered as good practice.

QueryBtn_Click(this, EventArgs.Empty).
Kaspars Ozols
  • 6,967
  • 1
  • 20
  • 33
  • 1
    I dont think this comes close to answering his question. – crthompson Dec 06 '13 at 07:24
  • Actually, it does. System.Timer is executing on the separate thread, but System.Windows.Forms uses the same UI thread. This allows you to keep all the references and execute logic related to UI. – Kaspars Ozols Dec 06 '13 at 07:27
  • Calling an event handler directly is a [very bad coding form](http://stackoverflow.com/questions/984270/c-is-calling-an-event-handler-explicitly-really-a-good-thing-to-do/984303#984303) – crthompson Dec 06 '13 at 07:32
  • I didn't say you should do it. I just wanted to point out that event handler just as any other method/function. – Kaspars Ozols Dec 06 '13 at 07:35
  • Its implied by your answer that its ok to do. – crthompson Dec 06 '13 at 07:36
  • 1
    Sorry to be unclear. Edited my answer so it is not misleading. Thanks for pointing it out. – Kaspars Ozols Dec 06 '13 at 07:39