This project is read-only.

ModernUI Started Externally (Possible bug?)

Aug 13, 2013 at 1:51 AM
Edited Aug 14, 2013 at 7:17 AM
Hello,

I have been frustrated for hours, and cannot find a solution.

I am trying to start up a mui:ModernWindow Class defined in a WPF project, "from a Windows Form Project," by referencing the WPF project from the Windows Forms project.

The reason this being is because I have an ApplicationContext in the Windows Forms project that requires the default project to be Windows Forms, and not WPF.

I can start and run the WPF project successfully when it is set as the startup item. Everything works 100%.

However, whenever I try to reference to the WPF project from the Windows Forms project, by doing the following:
Dim x As New ModernUIExperiment.main
x.show()
Where the WPF mui:ModernWindow is the "main" class.

Doing this brings up the window, as expected. However, when clicking the link that shows the user control, an infinite line of "loading dots" appear.

The guide I have followed is below:
My first Modern UI app

Things I have tried to resolve the problem that did not work:
  • Set the Source Property for the link externally during runtime:
Dim x As New ModernUIExperiment.main
x.ContentSource = New Uri("/ModernUIExperiment;component/stuff.xaml", UriKind.Relative)
x.link.Source = New Uri("/ModernUIExperiment;component/stuff.xaml", UriKind.Relative)
x.Show()
  • Copy exactly as best as the IDE would let me, Reference-to-Reference of the WPF project to the Windows Forms Project
However, I did note that I was able to get this method to work, from a separate WPF project, to WPF project containing the ModernUI using the following:
Dim x As New ModernUIExperiment.main
x.ContentSource = New Uri("/ModernUIExperiment;component/stuff.xaml", UriKind.Relative)
x.link.Source = New Uri("/ModernUIExperiment;component/stuff.xaml", UriKind.Relative)
x.Show()
The same exact code, but it works, 100% as expected.

So I have come to the conclusion that it's something to do with the startup project being WPF created. In my opinion, this whole situation seems like a bug to me.

If there's is anything I am overseeing, or if you have any questions or comments, feel free to ask. Any help is greatly appreciated :).

P. S. I am using Visual Studio 2012 Express, with Visual Basic

EDIT:
I did notice however, if I tried to set the "x.ContentSource" from a Windows Forms project, I get the error: "Object reference not set to an instance of an object." in PresentationFramework.dll. This may be a clue to why this is happening.

Thanks,
  • Jake M.
Aug 14, 2013 at 7:13 AM
Edited Aug 14, 2013 at 7:20 AM
After some more experimenting, I have come to the conclusion that the root cause occurs when setting the ModernWindow property "ContentSource", either through XAML or programatically. While it does technically get set, through some testing:
Dim x As New ModernUIExperiment.main
x.ContentSource = New Uri("/ModernUIExperiment;component/stuff.xaml", UriKind.Relative)
x.link.Source = New Uri("/ModernUIExperiment;component/stuff.xaml", UriKind.Relative)

MsgBox(x.ContentSource.OriginalString)

x.Show()
It does not get a null reference exception in my project's executable (as it would if I did not use the New keyword, so it does get set). However, even after confirming it gets set, and "then" showing the window, the null reference exception still occurs in PresentationFramework.dll.

I can still set the link.Source property only, and everything except the "infinite loading dots" and ContentSource works fine (to my knowledge).

Again, this does not happen in WPF projects, but only Windows Forms projects. I feel like a reference is missing, but I even tried adding all possible references under the "Assemblies" section, and that didn't even work. I get no errors, no warnings, no messages, nothing.
Aug 18, 2013 at 8:33 PM
Make sure a valid WPF Application object is created as well, and the Application.Resources dictionary is filled with the mui resource files. See also App.xaml of the demo app (available in the source code).
Aug 19, 2013 at 5:46 AM
The main project does has a generated WPF User Control already, and is actually being used in an ElementHost. Could you provide some examples on how to fill that dictionary with resource files? I'm still fairly new to WPF. I did give that project an appropiately modified Application.xaml (which is what I assumed you meant), and that did not resolve the issue. Instead, I get an error:

'Application' is ambiguous, imported from the namespaces or types ;system.Windows.Forms, GUI'.

The project I am attempting to store the ModernUI window in is a Windows Forms Application.
Aug 19, 2013 at 11:58 AM
I've created a sample forms project that properly initializes and displays a mui window. Download here
Aug 19, 2013 at 4:16 PM
Edited Aug 19, 2013 at 6:58 PM
Thank you for the help. This does create the window as expected, but this is not the part I am stuck at. I have gotten this far. The part of loading a WPF User Control into that MUI window is what the problem is. What's odd though (and this has happened on several occasions) as soon as an add an WPF User Control through the IDE, creating UserControl1, the following errors occur:

Error 1 The name "ModernWindow" does not exist in the namespace "http://firstfloorsoftware.com/ModernUI". C:\Users\Jake\Desktop\formsapp\FormsApp\MuiWindow.xaml 1 1 FormsApp
Error 3 The name "LinkGroup" does not exist in the namespace "http://firstfloorsoftware.com/ModernUI". C:\Users\Jake\Desktop\formsapp\FormsApp\MuiWindow.xaml 10 9 FormsApp
Error 5 The name "Link" does not exist in the namespace "http://firstfloorsoftware.com/ModernUI". C:\Users\Jake\Desktop\formsapp\FormsApp\MuiWindow.xaml 12 17 FormsApp

Even though it "just" worked. This has happened on multiple computers of mine, and multiple installations, so I know it's not my copy of Visual Studio.

What I typically do to resolve this issue is to re-add and remove the reference to FirstFloor.ModernUI until it works, but even if I do get it to work, the window still won't load the WPF user control.

EDIT:

I was able to add the WPF User Control, and set the Source property, despite the xaml errors. It ran and displayed the user control just as expected. I would like to boil down what specific aspect caused this success though, so I can apply it to my application :).

Also, where is the ResourceDictionary located? In my project, I typically embed it into the MUI window itself. In your example, I couldn't find the file it was stored in.
Aug 19, 2013 at 9:40 PM
Hmm, interesting issue. Adding and removing mui references until it works doesn't sound like a solid workaround. Why don't you keep your WPF app and Forms app completely separate and use Process.Start from within your forms app to lauch the WPF app?
Aug 20, 2013 at 2:17 AM
I have tried that, and it does work. However, as a preference I wanted to keep the GUI in the executable, to avoid setting a bunch of handlers (around 100) using the AddHandler keyword, and avoid the GUI being in a separate DLL.
Aug 20, 2013 at 3:25 AM
Edited Aug 20, 2013 at 3:25 AM
I have found the solution :D.

By analyzing some of your code, it turns out all that I need to get this to work in Windows Forms is to add the follow code before showing the window:
If Windows.Application.Current Is Nothing Then
    Dim app As New Windows.Application
End If
Thanks for all your help :).
Aug 22, 2013 at 4:42 AM
Wasn't sure if I should have started a separate thread for this or not, because it pertains to the example earlier, and other instances of Modern UI.

In my project (and yours for testing) I added some controls to a user control, such as a textbox, button, etc. What I noticed though however, is that in the textboxes, or anything with text, I can't type in them. Only the backspace key works. Any ideas on this?
Aug 22, 2013 at 1:01 PM
I think displaying a WPF window in a forms app is not a recommended practice at all. Unless you have very good reasons to do so, I would suggest separating the two and launch WPF apps using Process.Start.
Aug 22, 2013 at 1:29 PM
Alright, I'll try that and see how it goes and get back to you.
Aug 22, 2013 at 2:50 PM
I tried this in a WPF Class Library project (what I would consider more stable than a Windows Forms Class Library project), and it still did not work. I was calling from a Windows Forms project. However, when done in a pure WPF application, the textboxes work. So I've come to the conclusion that my Windows Forms project is missing something other than:
If Windows.Application.Current Is Nothing Then
    Dim app As New Windows.Application
End If
It doesn't have an Application.xaml, dunno if that has anything to do with it or not. I would assume it would have something to do with event handlers. The reason why I want to stick with Windows Forms, is because the core of my program was written in it originally, and didn't want to port several thousand lines of code. However if this is what it takes, I'll leave it as a last resort.
Aug 23, 2013 at 2:39 PM
I also tried adding an Application.xaml to my project, and set the Modern UI resourcesthere as shown in the guide. This works on a regular WPF project, just like the guide shows. However in my Windows Forms one, it doesn't. Is it possible the fact that the textboxes not working and the universal resources not loading could be related?
Aug 26, 2013 at 2:08 PM
Edited Aug 26, 2013 at 2:10 PM
Just adding an App.xaml to a WinForm project, doesn't do anything. In a WPF project, code is generated that ensures the App class is created in the main entry point. A file named App.g.i.cs is created in obj\debug and contains the correct initialization. You'll need to mimic this in a forms project.

But again, I strongly advice against this, since it's not an official supported scenario. The focus issue you encounter with textboxes might be an indication of some problem with WM messages being handled incorrectly.

Code re-use should be fairly easy, you can reference your WinForm exe in your WPF project.
Aug 27, 2013 at 2:10 AM
I've decided to go through the route of a full WPF conversion with a brand new GUI. This seems time consuming, but I believe that overall will be more efficient and easier in the long run. Thanks for the advice.
Mar 12, 2014 at 4:39 PM
I have a Windows Forms app and show Wpf windows with no problems.
In case anyone else wants to use ModernUI from Windows Forms, here is what to do:-
// do all this before you show your wpf window
if ( System.Windows.Application.Current == null ) 
{ 
   var wpfApp = new System.Windows.Application();
   wpfApp.ShutdownMode = System.Windows.ShutdownMode.OnExplicitShutdown; // this allows the wpf window to be closed and then shown again.

   Action<string> addMergedDictionary = path =>
      System.Windows.Application.Current.Resources.MergedDictionaries.Add( 
         new System.Windows.ResourceDictionary { 
            Source = new Uri( path, UriKind.RelativeOrAbsolute ) } );

   addMergedDictionary( "/FirstFloor.ModernUI;component/Assets/ModernUI.xaml" );
   addMergedDictionary( "/FirstFloor.ModernUI;component/Assets/ModernUI.Light.xaml" );
   addMergedDictionary( "/FirstFloor.ModernUI;component/Assets/ModernWindowEx.xaml" );
}
You can also do this if you want your wpf window to be modeless:-
               var myWpfWindow = new myWpfWindow();
               System.Windows.Forms.Integration.ElementHost.EnableModelessKeyboardInterop( myWpfWindow );
               myWpfWindow.Show();