0

I have an application that has two mode-less windows. The first window, has a button to take input from the other window. My question is what is (is there?) the right way to call the second window for input and block the caller until user provides an input inside the text box. Here is a visual of what I'm trying to explain here:

enter image description here

  1. App starts. Main window opens
  2. User clicks on first button in main window -> second "modeless" window opens. User switches back to main window
  3. User clicks on second button in the main window -> second "modeless" window is activated and focused
  4. Second window now waits for input into the text box. This is where the question is: How to block the call from the main window, wait for input in the textbox, and return to caller only when user has entered input into the textbox, while not freezing the windows

I have this sudo-code as the solution for now but the loop is happening inside the main app code and it uses too much cpu just looping. Not sure if there is a better/right way to do this in C# and WPF specifically:

// input control mechanism
private object _inputLock = new object();
private bool _waiting = false;

// public string ReadInput() method starts waiting
do {
    // pass control to dispatcher to update ui
    inputTb.Dispatcher.Invoke(
        () => { },
        System.Windows.Threading.DispatcherPriority.Background
    );

    lock (_inputLock) {
        if (!_waiting)
            break;
    }
} while (true);

// input text box handler turns off waiting
private void SendInput() {
    lock (_inputLock) {
        _waiting = false;
    }
}
Ehsan Iran-Nejad
  • 1,697
  • 1
  • 15
  • 20
  • 1
    How do you know when the user is done entering text in the modeless form's input field? When the field loses focus? At a certain length? When they close the window or click a button? – quaabaam Aug 14 '20 at 18:56
  • 1
    Wouldn't a modal dialogue suit the workflow? They input text, click ok and the input is handed back to the parent window. – Andy Aug 14 '20 at 19:06
  • It does but for a better user experience I'm avoiding the modal dialogs. I'm listening the the "Key Up" event on the text box to capture Enter, and other direction keys. – Ehsan Iran-Nejad Aug 14 '20 at 19:46
  • 1
    You are doing something strange. You don't want to use the modаl windows, but at the same time you create it yourself only in your own, custom way. – EldHasp Aug 15 '20 at 02:43
  • And I ask you to describe the algorithm in more detail - it's not entirely clear: In the first window, you have two buttons. The second - contains fields for input values. Tthe first window is shown - the button for showing the second is active in it. Pressing this button creates and displays a second window. Both buttons in the first window become disabled. In case of correct entry in the second window, the save button is enabled. By clicking on this button, the data are saved and the input window is closed. If written correctly, complete your question with a detailed algorithm. – EldHasp Aug 15 '20 at 02:43
  • You don't need to that loop , to showing the second window simply use ShowDialog() instead of Show() , it can block the main window . – Maria Aug 15 '20 at 07:42
  • @EldHasp The sketch has steps on it but I spelled them out in the question. – Ehsan Iran-Nejad Aug 15 '20 at 20:55
  • @MitraM That's not the answer I'm looking for. I understand how modeless and modal windows work. This is an abstract of a much more complex situation I'm in. I'm making an addon for a much more complex piece of software and I'm wondering if this particular challenge has a good answer – Ehsan Iran-Nejad Aug 15 '20 at 20:56
  • One of the possible variant, if I understand the algorithm correctly. Add Dependecy Peroperty Flag in the input window. When you start typing, set this flag. In TextBox.TextChanged handlers, check the entered values ​​and if the input is correct, clear the flag. In the first window, bind IsEnabled to this flag. – EldHasp Aug 15 '20 at 21:38
  • 1
    I still think the best way to do this is to use a modal window though, but anyway if that loop solves the problem and the only issue is high CPU usage put an Sleep(1) in the loop to reduce CPU usage. – Maria Aug 16 '20 at 05:52
  • @MitraM This was super helpful. I added a `Thread.Sleep(50)` and it completely calmed down the cpu utilization. is it because this passed the control to os kernel for a short time? – Ehsan Iran-Nejad Aug 16 '20 at 22:42
  • 1
    Sleep(n) suspends the execution of the current thread until the time-out interval elapses. And gives processor to other threads which are ready to run. Please have a look at [this](https://learn.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-sleep?redirectedfrom=MSDN). – Maria Aug 17 '20 at 06:03
  • Thanks a lot @MitraM – Ehsan Iran-Nejad Aug 17 '20 at 21:21
  • @MitraM Works perfectly now: https://user-images.githubusercontent.com/8197916/90345805-bb81d700-dfd8-11ea-9eef-d6c6d81a7fd3.gif – Ehsan Iran-Nejad Aug 17 '20 at 21:31

0 Answers0