Strange focus issue with UserControl hosted in ElementHost - wpf

I have UserControl which is hoseted in ElementHost.
It contains DataGrid
When user presses enter or double clicks the row new window is shown (modalless), and when that window is closed window with ElementHost is activated back. The problem is that DataGrid loses focus.
Snoop showed me that visual tree has the following structure:
AdornerDecorator -> AvalonAdapter -> My UserControl.
Snoop shows that after activation AdornerDecorator has properties
IsFocusable = false
IsFocused = false
IsKeyboardFocused = true
IsKeyboardFocusWithin = true
What is an absolute nonsense to me.
When user hits Tab or arrow keys the first enabled UserControl's element receives focus.
I've read this post and I'm not happy with it:
Focus works differently for WPF and Windows Forms, and there were some
rough edges around here that we were unable to fix. If you have focus
inside a WindowsFormsHost and either minimize/restore the form or show
a modal dialog, the focus inside the WindowsFormsHost may be lost –
the WindowsFormsHost still has focus, but the control inside it may
not.
Now what? Relax and be happy?
And the very disapointing is inability to reproduce the problem in other applications.
Can anyone explain what are the reasons of such a strange behavior?
May be offer some workaround.

It is a known bug: http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/7d41218e-c2bb-4957-b0b4-aa24efc4d8c2/
So far the official word from Microsoft is the issue I've described
above is an acknowledged bug but will not be fixed for .NET 3.5. Also
this issue won't be fixed in the next version the .NET Framework (.NET
4.0).
(by kainhart)
But unfortunately the reference to connect is dead.
To workaround this bug I had to add IsVmFocused property to my ViewModel and also create my FocusHelper.IsFocused attached property which listens for element's IsFocused property change and bound VM's property.
You can see the xaml in this (task related) SO question: What is a Cached acessor in the context of DataBinding?

Related

WPF Listview touch issue on window 10: "an event of another datatemplate is triggered while it may not happen"

When using a WPF application on windows 10 with a touchscreen we encounter an issue with the listview. When working with a mouse it works fine.
We have created a simple test-project, which is used to simulate the problem on windows 10 and can be found on GitHub. A ticket is also created on MSDN
In short below a summary of the technical setup:
We use a grouped listview, and for each group, a togglebutton and
another (inner) listview.
The inner listview uses an ItemTemplateSelector binded to an
Datatemplate selector, to choose an datatemplate.
There are 3 datatemplates (checkbox, numeric, text) that will be
choosen based upon the type property of the bounded model.
Each datatemplate has a stackpanel. The stackpanel in the text en
numeric datatemplate is wired to an PreviewMouseDown event.
Important, the stackpanel in the checkbox isn't wired to an event.
This works in general well, however sometimes, when touching the checkbox, the
PreviousMouseDown of another template is triggered.
I would expect that this behavior may not happen, is that correct?
We found a workaround (*) for this issue but we didn't find the root
cause.
Why is the event of another template triggered?
I'm starting to believe that this could be an issue with WPF Listview
and touch behavior?
(*) If we know that sometimes an event is triggered from a wrong template,
we verify every event whether that event is originated from the right template and if not we do nothing.
Below you can see when tapping quickly on the checkbox the clickevent get's triggered.
Below more details of the code:
The datatemplates and the selector
The grouped listview with the inner listview and the itemtemplate selector
Below the code behind and the handler for the PreviewMouseDown event
Below an overview of the steps we have been taken in order to resolve
it, but none lead into a solution.
Since WPF is supporting touch and a touch on a screen is also "translated" into a mousedown event, I don't see a problem why not using a previewMouseDown event on a touch screen. I also didn't find any offical documentation of Microsoft in not doing this.
Anyway, I could no longer reproduce the problem that a touch on listviewitem is invoking another previeuwMouseDown event of a template of another listviewitem in the list by ....
Changing the PrevieuwMouseDown event by a Touchdown event!
I am glad to find a solution, however based upon many online searches, I feel there are many issues with thouch on WPF and often it's is not clear what the rootcause is. Like in this case I found a solution by trial and error, but why the problem occurs when using previewMouseDown, is puzzling.

disable all input controls in a WPF Window

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.

WindowsFormsHost is always the most top from WPF element

how to set the z-index windowsformhost that they are not always at the top of the WPF element ?
According to MSDN (Layout Considerations for the WindowsFormsHost Element)
A hosted Windows Forms control is drawn in a separate HWND, so it is
always drawn on top of WPF elements.
This is a design limitation
Another good article from MSDN that explains possible issues when using different graphical technologies in Windows is Technology Regions Overview
However googling I found that there seem to be some hackings for this (known as airspace restriction)
One hack (never tried it personally so not sure if it works) is at
this link
I've just encountered the same problem.
There is a potential workaround - depending upon the nature of the Windows Host window control and the WPF element you want to appear:
I bound the the WindowsFormsHost control's Visibility to a property on my view model to enable me to hide the host (and the controls on it) when I want to display the WPF that we want to appear over it.
Update, a few years later (2016-09):
My following answer, as noted by the top comment, is no longer valid, and was not available in the final version of .NET 4.5, or subsequent releases. Unfortunately, the link I included still has z-ordering information for HwndHosts present for the "current version" of .NET, which could lead some to believe this functionality does, in fact, exist. It doesn't. There is no work-around.
Original answer:
A year later, things have changed a bit with .NET 4.5. For those who stumbled upon this, much as I did, here is a more updated excerpt from Walkthrough: Arranging Windows Forms Controls in WPF on MSDN:
By default, visible WindowsFormsHost elements are always drawn on top of other WPF elements, and they are unaffected by z-order. To enable z-ordering, set the IsRedirected property of the WindowsFormsHost to true and the CompositionMode property to Full or OutputOnly.
All you need to do, when using .NET 4.5, is add the following attributes to your WindowsFormsHost element IsRedirected="True" and CompositionMode="Full" or CompositionMode="OutputOnly".
In my situation my WindowsFormsHost is in a two row Grid. The bottom row has a StackPanel in it that changes Height depending on what it contains. I handle that StackPanel's LayoutUpdated event to resize my WindowsFormsHost by subtracting it's ActualHeight from the Grid's ActualHeight. Be sure to use ActualHeight not Height.
void ResizeWinhost()
{
mainGrid.UpdateLayout();
detailPanel.UpdateLayout();
winHost.Height = mainGrid.ActualHeight - detailPanel.ActualHeight - 5;
}

WPF Validation with ContentPresenter

I have a WPF user control which needs to validate some fields. It is bound to a class implementing IDataErrorInfo.
When I set the user control as the content of my ContentPresenter in another, already open, window, I can see validation occurring, and error messages being returned, however, I don't get any validation adorner - e.g. the default red outline.
If I enter the field and leave it (triggering re-validation) the validation adorner appears.
Also, if I show the user control in it's own window it shows the validation adorner immediately.
(I'm using Caliburn IResults to do this underneath, e.g. Show.Dialog<VM>(); but I suspect this isn't related)
Can anyone offer any suggestion why the validation adorners aren't appearing immediately. (I had guessed animation on my ContentPresenter ContentChanged, however, I have removed this and still experience the problem.
thanks,
Chris
This is a known bug that exists in .NET 3.5. You may be able to implement a workaround, however if it is feasible, I would recommend upgrading to .NET 4 as this will take care of your issue with validation.

WPF Popup and WindowsFormsHost Problem

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.

Resources