I have some simple code for popping up a "dialog"-like thing over part of my application window. The idea is, the user must dismiss the dialog before continuing to work with that part of the page.
This works by hovering a large semi-transparent rectangle over the part of the page that is supposed to be disabled - which does a nice enough job of blocking clicks to the region. You see this sort of thing a lot in WPF and Web apps, I think.
The problem I have is, the user can still reach all those juicy blocked controls by tabbing to them using the keyboard. "No problem", I hear you say, "just set the IsEnabled on the panel to false, thereby blocking keyboard access".
Unfortunately, disabling the controls:
Doesn't look very nice
Tends to have unintended consequences with custom styles and bindings further down the tree
So, is there a better way to disable a part of the page, without setting the "IsEnabled" property, such that it doesn't change the visual appearance of any of the controls?
Thanks,
Mark
Can you put your "dialog" XAML in a popup window? Then, call ShowDialog() on the window to make it a modal window? If you don't want your popup to look like a standard window, you could always syle it to remove borders, etc.
I solved this by subscribing to the PreviewGotKeyboardFocus event, from the parent element in the tree, and then handling the event such that focus never gets passed to the children.
Also, I had to explicitly remove focus from the "disabled" controls as well, of course.
Related
Is there a way to make an entire WPF Window inert after a button click?
The window is invoked via Window.ShowDialog() and after use, the window is no longer needed for interaction but I leave it open to remind the user of the inputs in TextBox's, ListBox's, and give visual feedback via OxyPlot and so on. I leave it to the user to close the window manually.
One solution is to disable all buttons but that's tedious and it still leaves TextBox's functioning. That's not optimal because for anything to be functioning creates the wrong impression that the Window remains for anything other than looking at. It would be better for every control to be non-functioning by a single setting.
I did it by putting a name on the WPF window code behind and then setting .IsEnabled false upon the appropriate button click. All buttons, combo boxes, text boxes, and even OxyPlot became inert at that point and most parts were greyed out.
Consider creating a dedicated boolean dependency property in your code-behind or viewmodel and binding IsEnabled of every TextBox to the property.
I have created a custom popup to decorate my buttons with animated tooltips. I track Button.MouseEnter for the button to decide when to display the popup. I use Button.MouseLeave to determine when to hide the popup.
Problem is Button.MouseLeave is fired prematurely if the popup moves over the mouse cursor (its appearance is animated) despite the fact that I have set IsHitTestVisible = false for the popup and all its visual children.
Is this the way WPF is designed to work? I need MouseLeave to only fire when the cursor moves away from the button itself and not be influenced by the popup.
Thanks
I believe that the Popup control is actually contained within a window, which is why the popup can extend beyond the window bounds in some cases. (It's also why popup transparency is not supported in Silverlight.)
I believe that while the popup control is no longer processing "hits", the container window is, which is why you are losing your button's mouse focus.
I've not tested this, but you might try creating a template for your button and actually declaring the popup as part of the button (rather than below it). This may cause WPF to view the popup control as part of the button and eliminate the problem of losing mouse focus. This works in other scenarios, but I'm not 100% sure how this will work with a Popup.
EDIT: As a side note, the deault WPF tooltip allows you to override the template. I'm not sure what your goals are, but you may find it easier to change the appearance and behavior of the default tooltip than to try to roll your own, as a lot of these sorts of problems have already been solved in the default Tooltip.
I am working on a silverlight application with a significant number of invisible tab stops.
I am currently busy trying to track them all down and eliminate them.
I am aware that any control that inherits from System.Windows.Controls.Control can take focus and yet I still can't identify where the focus is be going for much of the time when I press tab to move round the UI.
So, my questions are:
Will everything that acts as a tab-stop also take focus (and visa versa)?
What, apart from anything that inherits from Control, can act as a tab-stop?
There is little point in something being a tab-stop if doesn't "also take focus". However not everything that can take focus need be a tab-stop, for example, a control may take the focus when clicked on by the mouse but not via the tab key.
In Silverlight there is nothing that can act as a tab stop that is not also a Control.
The Control class has a IsTabStop property which by default is true. If you have been building your own controls its up to you to build visual states to indicate that the control has the focus. If your control doesn't need the focus for any reason then clear its IsTabStop property early in its constructor.
I am hosting windowsforms control in WPF popup. Problems below:
If i make StaysOpen=False i can't interact with winform control. StaysOpen to false is required because when clicked outsidet the Popup region, it should close.
if i make StaysOpen=True i can interact with winform control but when i click outside the area of popup, it is not getting closed.
I tried setting StaysOpen=true in MouseEnter of popup and StaysOpen=False in MouseLeave, but MouseLeave fires as and when mouse is over winform control resulting in unexpected behaviour.
I even tried IsMouseCaptureWithin property of popup and found it does not work with winforms (i guess its a bug in framework).
Another problem, i was trying to close popup when root main form (which is windows form) is deactivated (pressed Alt+Tab), but this event (deactivate) is fired even when i enter into one of the controls in windowshostControl in popup.
Desired Behaviour:
should be able to host and interact with winform control in wpf popup.
on clicking on outside the area of popup, popup should close.
Appreciate any inputs.
Thanks.
I've had many problems with the defacto-standard popups in WPF, because they are in fact a new window with their own handle. This means if you drag your application around the screen, the popup stays put (it doesn't move with your window). It also means your popup has some strange behaviors and doesn't interact with your application in ways other controls normally do.
I've created 2 decorator classes to address this problem:
PopupDecorator.cs and
TimeoutPopupDecorator.cs
It's pretty simple to use:
Add a namespace declaration for the new popup classes. i.e.
xmlns:dday_wpf="clr-namespace:DDay.WPF"
Surround the area you want the popup to be able to be displayed with the decorator. i.e.
<dday_wpf:PopupDecorator x:Name="popup">
<dday_wpf:PopupDecorator.Popup>
... contents of popup go here ...
</dday_wpf:PopupDecorator.Popup>
... contents of panel go here ...
</dday_wpf:PopupDecorator>
It works pretty much identically to a normal Popup from that moment on.
This may not solve all your problems, but hopefully it helps.
This sounds a bit like my problem launching a modeless winform control from a WPF form.
Check out my question Why is my WPF textbox "kinda" readonly?.
The just being, based on what Doug said about popups being a window with its own handle, makes this applicable.
I have a custom UserControl which tries to recreate auto-complete for a textbox. When user types, the text is used to filter a provided collection of items and then a Popup displays a ListBox with items that match what user have typed.
Unfortunately, if user decides to switch away from the application to another window (browser, MSWord, anything!), the Popup remains on top of every other window!
Also, if I move my window (which hosts the custom control) with the popup open, the popup stays in place (and doesn't follow the window)! It's kinda funny but obviously not acceptable behaviour. I've looked around but only found one post about this that went unanswered for two years :(
Actually, I didn't realize that I had StaysOpen property of the Popup set to true.
<Popup StaysOpen="False" />
actually does the trick for me.
I had the same problem in a similar scenario. What I did was I subscribed to all posible "lost focus" events of the control and also got the window which hosts the control and subscribed to its GotMouseCapture and LocationChanged events. Event handlers of all those events are setting the popup's IsOpen property to false.
You can get the hosting window with this:
parentWindow = Window.GetWindow(this);
all other code is simply a lot of subscribing to events to do the same thing.
P.S. I'm not saying it's a pretty or optimal solution, but it works fine for me :)
According to the Popup documentation:
When Popup is displayed on the screen, it does not reposition itself if its parent is repositioned.
So it does not look like it would be a very good candidate for an autocomplete textbox. I think the class is meant more for showing information when you hover over an item.