1
votes

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();
    }
}  
1
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. - BradleyDotNET
That's why because I don't know how to do this without timer. Yes the timer in window1 check status in mainwindow. - user3455769
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. - Peter Duniho
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. - Peter Duniho
@user3455769: no offense intended, but that reply doesn't address any of the questions I actually asked. :( - Peter Duniho

1 Answers

0
votes

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.