WPF window inside a WinformHost Panel - c#

I am showing a WPF exe window inside another WPF application using winform host.
I have created a panel in main application and set it as child of winformhost.
mHostingPanel = new System.Windows.Forms.Panel()
{
BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle
};
mWinformHost = new WindowsFormsHost();
mWinformHost.Child = mHostingPanel;
and then I start the other window process and set hosting panel as parent.
WindowsAPI.SetParent(mProcess.MainWindowHandle, mHostingPanel.Handle);
My question is if I launch the application,Who will be rendering my Child WPF window whose parent is a winform panel.Will it be Direct-X or GDI context of Panel?
Also if I set Allowtransparency=True on child WPF application,The UI doesnt show up in hosting panel.

Found the reason.Its called airspace issue (when win32 and WPF trying to share pixels) and I dont think it can be solved by any framework API as microsoft denied it.
https://visualstudio.uservoice.com/forums/121579-visual-studio/suggestions/2644120-bring-back-the-hwndhost-isredirected-and-compositi
Mitigating AirSpace issues

Related

Winforms Control.ScaleControl method not fired when changing scale from OS on the fly without restartig winforms application

I have a kind of winforms applications, an VSTO Outlook addin. Within this application I am using a container that Outlook API provides and in this container you can embbed a Winforms usercontrol.
So now i want to use a WPF usercontrol in this application which I want to embbed within the container that Outlook API provides so what i have done is the following:
Create a Winforms UserControl
Whithin the Winforms UserControl created in step 1, I add an ElementHost container.
Finally, within the ElementHost container I embed the WPF usercontrol throguh the Child property of the ElementHost.
The Winforms UserControl has below properties set:
AutoScaleMode = dpi
AutoSize = true
And the ElementHost has the AutoSize property set to true.
Now if you change the scale from the OS and start the application, the Outlook container is resizing perfectly according to the scale selected in the OS.
In the Winforms UserControl I have overrided the following method, so any scale operation goes through there and I can handle the scaling factor and then apply it to the Outlook container:
protected override void ScaleControl(SizeF factor, BoundsSpecified specified)
{
base.ScaleControl(factor, specified);
// Record the running scale factor used
this.CurrentScaleFactor = new SizeF(
this.CurrentScaleFactor.Width * factor.Width,
this.CurrentScaleFactor.Height * factor.Height);
// Once I have the correct scale factor I apply it
// Do some stuff here
}
Above method is called every time my Winform application starts for first time. (It is ALWAYS called for first time).
Now I have a particular use case: With my Winform application already started and running, I change the scale from the OS, let's say, from 100% to 150%, so the WPF user control resizes and t causes also the ElementHost and Winforms user control to resize to fit its content (in this case the WPF user control) but what I notice is that the above method ScaleControl is not being fired for the Winforms user control.
So my question is: Why do the ScaleControl method is not being called when Winforms user control resizes? Also, as ScaleControl method is not being fired, is there any event in winforms that I can handle and which it is fired every time user explicitly changes the scale from the OS so I can then get the scale factor?
Note: As I cannot specify ore than 5 tags in the post, i must say that i am using .NET Framework 4.5 (Standard).

Classic forms control cannot resize in WPF environment

I've added a regular forms control but I cannot resize it. Instead I have to resize host.
MSDN sample: Hosting a Windows Forms Control in WPF
System.Windows.Forms.Integration.WindowsFormsHost host =
new System.Windows.Forms.Integration.WindowsFormsHost();
MaskedTextBox mtbDate = new MaskedTextBox("00/00/0000");
host.Child = mtbDate;
this.grid1.Children.Add(host);
mtbDate.Width = 200; //Not work!
host.Width = 200; //Workaraound...
How can I resize the control, not the host?
This page gives a lot of information about hosting WinForms controls in WPF: http://msdn.microsoft.com/en-us/library/ms744952.aspx
The short story is that you are not supposed to resize the textbox- that will be ignored/overridden. Instead, resize the WindowsFormsHost (either in WPF or via WPF dynamic layout)

"Clear" window to make room for new user controls?

I'm usually working with Windows Forms Applications, but I'm currently needing Windows Presentation Foundation for design purposes.
What I am needing to do is clear out the current open window and fill it with new user controls as though a new window has been opened. In short, open a new window without actually opening a new window, similar to navigating to a new page in a web browser. (Still the same window open in the Taskbar, no extras.)
I was unsure if there was a specific class or control that made this easy to do. If someone could enlighten me on the way to do this in WPF, I would be very pleased.
Thanks.
There are a number of possible ways - here are a few that come to mind:
Navigation
In WPF, you can actually navigate to different xaml pages. In this scenario, you would define a number of pages that a main page could navigate to.
http://msdn.microsoft.com/en-us/library/ms750478.aspx
Programmatic
You can do it the old school way and just clear out all of the controls in a window. For example (in the context of a window):
StackPanel stackPanel = new StackPanel();
stackPanel.Children.Add(new MyUserControl1());
stackPanel.Children.Add(new MyUserControl2());
this.Content = stackPanel;

Casting Windows.Controls.UserControl to Windows.Forms.Control

Can we cast a WPF User Control to a form control??
I'm sorry you can't. WPF works very differently internally from Winforms: Winforms uses the controls provided by the Windows OS (where each control has a window handle), where WPF uses DirectX to do the painting.
You can host WPF controls inside winforms applications (EDIT)and vice versa (with limitations) but that is perhaps not what you're after.
I tried this out:
TouchScreenWPF touchUI = new TouchScreenWPF();
ElementHost elementHost = new ElementHost();
elementHost.Child = touchUI;
Control userControl = new Control();
userControl.Controls.Add(elementHost);
The form contains the usercontrol, but does not display anything when I include a WPF User control. It works with a single button though... Am I missing something there?

WPF equivalent to Silverlight "RootVisual"

I am trying to port an application from silverlight to wpf. Unfortunatley I am new to both. Is there an equvivalent to the following Silverlight code in WPF?
private static Canvas GetCanvas()
{
var uc = Application.Current.RootVisual as UserControl;
if (uc == null)
{
return null;
}
return uc.FindName("ChoiceCanvas") as Canvas;
}
Currently I am using
Application.Current.MainWindow.FindName("ChoiceCanvas") as Canvas;
But this doesn't work, perhaps because ChoiceCanvas is something located in a UserControl and not in the MainWindow?
There is no RootVisual property in WPF. As far as I understand, the "Window" is the "root". You can get the Window that any WPF (D.O.) object belongs to by running the static method Window myWindow = Window.GetWindow(myControl);
FindName won't work becuase the Canvas exists in the namescope of the UserControl, try using the LogicalTreeHelper instead.
var canvas = LogicalTreeHelper.FindLogicalNode(
Application.Current.MainWindow, "ChoiceCanvas") as Canvas;
The current window is the root visual.
From MSDN WPF Graphics Rendering Overview:
The root visual is the top-most element in a visual tree hierarchy. In
most applications, the base class of the root visual is either Window
or NavigationWindow. However, if you were hosting visual objects in a
Win32 application, the root visual would be the top-most visual you
were hosting in the Win32 window. For more information, see Tutorial:
Hosting Visual Objects in a Win32 Application.

Categories

Resources