WPF modal window behaves weird - wpf

I 'm running into a situation i don't understand and want somebody to enlighten me if possible.
Created a WPF application. For sake of simplicity consider this application to be one window. I put some controls on this window, amongst others there is a TextBox control (let's call it TB).
There is a requirement that this TB must always have the focus (in case someone types something or something is read through the barcode-scanner it should appear there).
I thought implementing this with the help of a timer: every second the focus is transferred to the TB.
Until now everything works fine (as expected).
The weird thing is the following: let's say a new user wants to use this window, so she has to sign in. I thought implementing this with a new Window object (let's call it W2), calling it this way:
W2.ShowDialog();
This W2 window should be modal (bear in mind that the timer still executes).
The crazy thing is that under Windows Vista this works perfectly as expected (this means W2 is modal and the user can to what she should do on W2), BUT on Windows XP as soon as the user wants to type something in a textbox of W2 the focus is set back to TB on the initial Window (as far as i can interpret: this means W2 is not modal!!!? am i right?).
How can i overcome this situation?
Is this the right approach?
Thanks in advance

Make sure to set the Owner property of W2 to your main Window.
From the referenced docs:
When you open a child window by calling ShowDialog, you should also set the Owner property of the child window.

I am not sure this setting-the-focus-back-every-few-seconds is such a good idea. It is always possible that some input will come in the interval between a lost and got focus state (and be lost). Alternative solutions are catching the PreviewKeydown event on the form that the TB resides on and somehow set the output of a barscanner to the TB too.

Related

A proper solution to a WPF application using On Screen Keyboard

I´ve been working for some time on a good OSK solution for my WPF apps, that are running on a tablet. But it´s hard working with the OSK.exe and tabtip.exe, because of several bugs, strange behaviour and no standardized solution to this ordinary problem.
What I (probably) need is a custom textbox control, which inherits from System.Windows.Controls.TextBox, and overrides some methods.
The simple requirements for this textbox should be:
1. When a user clicks in a textfield, the tabtip.exe (or alike) keyboard should pop up at the bottom of the screen (default).
2. If the keyboard pops up on top of the textbox, the contentframe should scroll so that the textbox is visible.
3. When the textbox loses focus, the keyboard should close automatically, except if the user clicks on another textbox.
This seems like pretty standard behaviour right? Well I´ve looked a long time for solutions (there is no standard microsoft way which is kind of weird), and as said I´ve tried making my own but with no luck. For example, sometimes when I try to kill the process, it fails. When I click the close button in the upperright corner on the keyboard, like 5-6-7 times, it closes. The behaviour from PC to tablet is not consistent. The ScrollViewer.ScrollToVerticalOffset(x); sometimes doesent work on a tablet, and so on.
So does any of you know a good solution to this common problem?

WPF Modal dialog goes in background

I have problem with an application where modal WPF dialog occasionally goes behind the main application window. This hapens when I click button on the dialog which does some processing and updates controls (through binding) in the main application window. When it goes in background - clicking anywhere in the application brings it back into foreground.
var dialog = LoadDialogWindowThroughMEF();
dialog.Owner = Application.Current != null ? Application.Current.MainWindow : null;
dialog.ShowInTaskbar = false;
dialog.WindowStartupLocation = WindowStartupLocation.CenterOwner;
return dialog.ShowDialog();
The above code shows how I open modal window. This happens very rarely.
Does anybody know what could be the problem?
I'm not sure I have an answer for you, but I can share some of my thoughts:
Every time I've encountered this type of problem, it happened because the Owner wasn't set properly. So, I'd try to not set the Owner and see if that makes the problem reproducible. You need to be absolutely sure that Owner is set to the correct parent window at all times1. You might also want to check that it is the actual MainWindow of your application that are supposed to be the parent. I think that most of the time it is beneficial to be explicit2 in your code. In this case that means that it is better to assign the known parent (maybe you have a reference to the parent somewhere that you could use), rather than relying on the Application.Current to provide you with that reference. Doing so will put you in control of the assignment to Owner. It could even make it possible to get rid of the ?: operator since you would have the means to control the reference even during unit testing.
I also want you to make sure that the code that is actually updating the parent window doesn't in any way force focus to a specific control on the parent window, or anything like that. (As long as the correct parent is set as Owner, I don't see this as a likely problem.)
I hope this helps you, but I understand if it doesn't. The fact that your dialog reappears when you click the parent window disproves some (or all!) of my points...
1 Except when running your unit tests, but that's a completely different matter.
2 As in the first meaning of the word according to wiktionary.org/wiki/explicit, and as opposed to implicit.

Avoid second click in silverlight button MVVM

I've seen I have a problem with several users that use to double-click in buttons.
I have several buttons bound to commands that launch many actions.
For example there are two windows that communicate between them through a mediator so when I click "close the other window", the bound command sends a "CloseTheOtherWindowMessage". The problem is that when a user makes double click it tries to close the window a second time and, as expected, it crashes.
I've tried to set the window BusyIndicator as IsBusy when I press the button but my finger is quicker than MVVM and it still let me double-click before it starts showing the BusyIndicator.
I've found many examples of how to only admit double click in MVVM using interaction.Behaviors but I want just the opposite. Is there any example or other good and general solution for this problem?
Why is it "as expected" when it crashes? A crash should never be "as expected".
Your finger shouldn't be "quicker than MVVM". The Dispatcher thread always acts deterministically and sequentially. Do you use a multi-threaded approach?
In the command's Execute method or handler, raise its CanExecuteChanged event, and the binding engine will immediately call CanExecute(...). Make it so that this method will return false the second time. Maybe use a timer, or, better yet, you can logically determine by your view model state alone that the action is not possible right now (i.e. because IsOtherStuffAvailable is currently false).

WPF: Determine if a Panel is visible to the user

I have a WPF usercontrol (myGraphicControl) in a tab (WPF application).
When the form size changes, I redraw the graph in myGraphicControl.
Since the redrawing operation is a I need to do it only the control in in the visible tab.
How the WPF (user)control can detect if it's "visible" actually or not?
PS.
by Visible I mean that user can see it.
say, if a Visible TextBox is located in the currently invisible tab, this textBox is not visible by the user.
I don't believe there is a quick-fix solution here, but you may be able to do something using UIElement.InputHitTest(Point).
You could make a call similar to
//get the coordinates of the top left corner of the child control within
//the parent
var childTopLeft = childControl.TranslatePoint(new Point(), parentControl);
//check whether or not the child control is returned when you request the element
//at that coordinate through hit testing
var isVisible = (parentControl.InputHitTest(childTopLeft) == childControl);
However, I should point out that I haven't tried this myself, and that it probably won't work in the following scenarios:
Transparent items - generally, transparent backgrounds cause hit testing of a control to pass to the parent
Partially occluded items - you can only hit-test one point at a time, so if only part of your child control is visible you will have to check the correct point
I've found that while Steve's method generally works, it works much more reliably if you get a point from somewhere in the middle of the child control. I'm guessing that maybe layout rounding somewhere along the way makes the InputHitTest check somewhat inexact. So, change his first line to the following and you're golden:
var childTopLeft = childControl.TranslatePoint(new Point(childControl.RenderSize.Width/2, childControl.RenderSize.Height/2), parentControl);
Maybe UIElement.IsVisible will be helpful? It works for tab contents well.
Anyway you can use a solution described here.
I have one more solution. The current implementation of TabControl removes inactive tabs from visual tree. So, another way to determine whether your element is visible is to find PresentationSource. It will be null for elements of inactive tabs.

Need to control "Z Order" of windows within WPF Application

I have an application that, due to OpenGL airspace issues, has to host several controls in separate, exclusive windows. This is working quite well, but I am setting all of the windows to TopMost = true, which means that they do stay showing even when they lose focus, but they also overlay other applications. Also, it kind of binds me to using only one window at a time for this. Activate() doesn't work either.
I found that setting the windows' owners to the main app window allowed them to always float on top.
Inside the control that mediates the content and measurement of the child window:
InnerWindow.Owner = Window.GetWindow(this);
this being the windowHostControl hosting this window.
I use to combine Activate() and Focus() methods to show a hidden Window. Can you try using Focus() and let us know if this is working ?

Resources