CLR exception STAThread attribute required for ElementHost in WinForms app - winforms

I have a WinForms VB app, using Visual Studio 2010. I am using the WPF DocumentViewer, so it is hosted by the ElementHost control. In my AppMain_Form.Designer.vb, when the follopwing (generated) statement is executed:
Me.rv_doc_vwr_host = New System.Windows.Forms.Integration.ElementHost()
I get an exception (which I had to enable CLR exceptions for the debugger to get):
"The calling thread must be STA, because many UI components require this."
However, in my research for this problem, I found the following:
1) Windows Forms applications are SingleThreaded by default.
2) The Main procedure is generated automatically for Windows Forms applications, and it is hidden.
3) A Main procedure can be manually coded, but this requires disabling the Application Framework, which I believe is rather necessary for a Windows Forms application.
So, why is this exception occurring if the Windows Forms application is SingleThreaded by default? If not, how can I mark the Main procedure as STAThread if it is hidden? Why did I have to enable CLR exceptions to catch this? Prior to enabling CLR exceptions, this did not show up in my testing, but when I ran my app outside of Visual Studio, it displayed an exception box briefly about creating the main form, but before I could get any details it was replaced by my splash screen, then my main form. The app worked normally after that. However, I cannot deploy it with an exception message being displayed every time it starts up.

Related

CefSharp.Wpf: FileLoadException when trying to load assembly

We have an old legacy application that is running with MS Access. We are in the process of migrating it to WPF. For that we created a WinForms control, that is showing our new WPF stuff in an ElementHost. This WinForms control is then somehow used in a COM ocx which then is placed on a MS Access form. This works so far, and for the time being this is like it is and I can't change it.
Until now we used the built-in WebBrowser control from .NET to show web sites, but since this control is based on IE 11, we are looking for a replacement. WebView2 is not working in an ElementHost, so now we are investigating and testing CefSharp for WPF.
In all of my stand-alone tests it worked so far, but when I tried to integrate it into our software today I stumbled upon a problem and I'm not sure how to fix that.
When I put the ChromiumWebBrowser control from CefSharp onto our WPF window and ran our software I got an IO.FileLoadException for the file CefSharp.Wpf. Checking that with fuslogvw.exe I've seen, that .NET looked for that file in the directory where the MSAccess.exe is situated, probably because this in fact is the executing assembly.
So I registered an AppDomain.CurrentDomain.AssemblyResolve event to manually load the necessary files from where they are situated. This worked for
CefSharp.Wpf
CefSharp
CefSharp.Core
But then it tried to load CefSharp.Core.Runtime and although this assembly is present I get an IO.FileLoadException (this file or one of its dependencies can't be found) when loading this assembly. I assume that it tries to find one of its own dependencies (non .NET) and looks for it in the wrong place (maybe the MS Access directory again?).
Do you have any suggestions how I can tell CefSharp and all of its dependencies (direct or indirect) where they can be found and where they should be loaded from?

Exceptions in WPF Word Addin are not being handled

I am creating a WPF Office add in, and I would like to handle all exceptions in one place. To do this I use the following code in the constructor of my MainWindowViewModel:
Dispatcher.CurrentDispatcher.UnhandledExceptionFilter += new
DispatcherUnhandledExceptionFilterEventHandler(HandleAllException);
In my test environment I host the WPF app from a console application project, and exceptions are handled as expected. When I host the WPF app from within word however, nothing happens when exceptions are thrown. There is no notification at all that there has even been an exception, other than in the output window in visual studio. Does anyone have any suggestions as to what I might be doing wrong?
I have solved the problem by changing the way in which I launch my WPF app. I believe the problem was related to this.

Returning the control back from the JIT debugger to the application

I am having trouble with the JIT Debugger. I have a windows forms application which calls into a .NET assembly which has a function called calc(int,int) which has a break point set using the System.Debugger.Break(). This assembly is loaded when I click on a button in the forms application. Now, when the breakpoint is hit the JIT debugger asks me if I want to debug the application. I choose to do so and select a current instance of visual studio which has the project for the forms application I was running loaded. VS successfully breaks at this call. Now when I click on run I expected the forms application to return to a state where I can interact with it again.Instead, what I get is a "ghost" window of the forms application. Is there anyway to get around this problem? I know attaching the forms application to the VS debugger before the breakpoint is one solution. But is there any way to get this behavior when I use the JIT debugger?
Thank You.

Enable application framework settings in WPF projects?

What it is the option Enable application framework that I found in Visual Studio under VB.NET WPF projects Application settings?
I found it enabled by default and the "Shutdown mode" configured as "On last windows close". But for me is not really clear what does it mean that setting and also the other settings listed in that combo box.
It means if you have an application that has multiple forms, the application terminates when the last form of that application has been closed. It doesn't matter which form is the last form you close. If you close all forms that belong to that application the application terminates.
"When Startup Form Closes" means that the application terminates when the form that is listed in the "Startup from:" Combobox gets closed. This means if you still have forms open but close the form that was set as your startup form, all other forms get closed aswell and your appliction terminates.

Retrieve baseUri w/o resorting to Application.Current

My custom controls are not loading in VS.NET's designer because of a null reference exception. It's got everything to do with the way I am retrieving the baseUri of the application when it runs in the browser:
_uriPrefix = Application.Current.Host.Source.AbsoluteUri.Substring(0,
Application.Current.Host.Source.AbsoluteUri.IndexOf("/ClientBin")).Trim();
According to the exception details and the help file I'm directed to (here) I'm not correctly designing my app for a runtime that's not the browser (i.e. the new WPF editor in VS.NET or Expression Blend).
So, the question is how do retrieve the baseUri (the http://localhost:#### part of my application) if I can't use Application.Host which apparently is null during design time? is there a safe way to do this so I can load my custom controls in a designer?
To eleborate on the problem and solution (i wasn´t finished writing it when you posted your own answer)
Your problem is the runtime context you are in.
When your page is run as on a ASPX.Net page, your are hosted by the IIS->ASP.Net pipeline. This application will give your the HTTPContext and your Application.Current is refering to the W3WP.EXE process in which the ASP.Net pipeline is serving your page.
When your page is displayed in the MS Visual Studio designer it does not provide this HTTPContext since there is none. The request to render your control did not come through an HTTP request, but the Visual Studio designer running inside Visual Studio.
To have your control be displayed correctly during design time, you´ll have to add ´design time support classes´. There are a number in the .Net framework you can use directly, but for custom serialization (writing the server ASP.Net tags or rendering a HTML preview with styling) you´ll have to put in some more effort and write your own designer classes.
Hope this helps,
Duh! I hate/love when I do this. I'm answering my own question (again). I can use the DesignerProperties.IsInDesignTool boolean to test if I'm in design mode or not:
if (!DesignerProperties.IsInDesignTool)
_uriPrefix = Application.Current.Host.Source.AbsoluteUri.Substring(0,
Application.Current.Host.Source.AbsoluteUri.IndexOf("/ClientBin")).Trim();
Now I can view my custom control in the new VS 2010 editor. Yeah!

Resources