1

I need help in some problem. In MainWindow WPF i read status from device and 0 is normal work, 1 is other status. I want to open new window when i get status = 1 and close it when i get 0. I try do it with timer and showDialog. New window is created but status in MainWindow doesn't change until i close new window manualy. Any sugestion how to do it without timer? Maybe some sample.

Thanks in advance.

MainWindow - timer tick:

public void t1_Tick(Object Sender, EventArgs e)
{
    HttpWebRequest request7 = WebRequest.Create("http://localhost:8080/datasnap/rest/TAutomatServerMethods/uCard") as HttpWebRequest;

    using (HttpWebResponse response7 = request7.GetResponse() as HttpWebResponse)
    {

        StreamReader reader7 = new StreamReader(response7.GetResponseStream());

        string json7 = reader7.ReadToEnd();

        //  MessageBox.Show(json);

        JObject o7 = JObject.Parse(json7);
        int status_int = Convert.ToInt32(o7["result"][0]);

        if (status_int == 1)
        {
            uCard uc1 = new uCard();
            uc1.ShowDialog();
        }
}

Window1 - close window

public void t1_Tick(Object Sender, EventArgs e)
{

    if (MainWindow.status_int == 0 )
    {
        this.Close();
    }
}  
12
  • 2
    Why is there a timer here? Is that to check the variable? I feel like some code is missing. What status in "MainWindow" is not changing? By the way; ShowDialog will block the executing thread until it is closed. Commented Oct 17, 2014 at 23:13
  • That's why because I don't know how to do this without timer. Yes the timer in window1 check status in mainwindow. Commented Oct 17, 2014 at 23:17
  • 2
    I agree that more context is needed. A clarification on ShowDialog: it doesn't block the thread per se. Window messages are still pumped, UI still gets to draw. These are things that happen in the context of the ShowDialog method. But what does get blocked is execution of the calling method; that method (here, "t1_Tick") won't return - or even get to execute further - until the ShowDialog method returns, which won't happen until the dialog window is closed. Commented Oct 17, 2014 at 23:19
  • 1
    Updated by what function? What causes that function to execute? Are you sure it's able to execute when your other window is displayed? What do you mean by "status_int is in the same timer method..."? To me, that means it's a local variable. But if it's a local variable, how do you expect the other thread to examine it? Finally, if it's not a local variable but truly shared between the threads, have you marked it volatile to ensure that the code executing is always seeing the current value? Note that all of these questions would not need answering if you'd posted enough code. Commented Oct 17, 2014 at 23:36
  • 1
    @user3455769: no offense intended, but that reply doesn't address any of the questions I actually asked. :( Commented Oct 17, 2014 at 23:42

1 Answer 1

0

First, you need to create an event to raise when the value changed:

public event Action<int> StatusChanged;

And a property to raise it when it changes:

//This is very close to a standard INotifyPropertyChanged
private int status_int = 0;
private int Status
{
    get { return status_int; }
    set
    {
       if (Status != value)
       {
           status_int = value;
           StatusChanged(value);
       }
    }
}

Get rid of the status int check in your timer, just set the variable:

Status = retrieved_status;

Register for the event:

public MainWindow()
{
    StatusChanged += HandleStatusChange;
}

And your "ShowDialog" to pass the actual instance of the form in:

private void HandleStatusChange(int newValue)
{
    if (newValue == 1)
    {
       //Threaded so we don't hang the timer callback
       new Thread(() =>
       {
          uCard uc1 = new uCard(this);
          uc1.ShowDialog();
       }).Start();
    }
}

Then in your popup, your constructor would be:

public uCard(MainWindow window)
{
    window.StatusChanged += CheckForClose;
}

You would get rid of that timer and have:

private void CheckForClose(int newValue)
{
    if (newValue == 0 )
    {
      this.Close();
    }
}

Its still pretty bad, but a lot cleaner and maintainable. More importantly, it will actually work.

Sign up to request clarification or add additional context in comments.

3 Comments

In uCard window i get: An unhandled exception of type 'System.InvalidOperationException' occurred in PresentationCore.dll "The calling thread must be STA, because many UI components require this"
@user3455769 Then mark it STA whichever thread its complaining about. I'm not sure why any of that would need to be STA, but it won't hurt you.
Ok. Now is working properly. Thanks once again BradleyDotNET.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.