XAML resources aren't loaded when calling from different project - wpf

I have a WPF project with some styles in XAML in Application.Resources. This works perfectly fine. But when I open a window from this project from another one (this one is a console application), the resources from XAML aren't loaded. When I first tried it, I got a XamlParseException on StaticResource calls in XAML, so I changed it to DynamicResource and now the style just doesn't get loaded. How do I fix this?
The code I use:
[STAThread]
static void Main()
{
App app = new App();
MyWindow wnd = new MyWindow ();
wnd.Show();
app.Run();
}

You should call the Run method that takes a Window parameter. In your current code, you're creating and showing the window before running the app, which means the application resources aren't loaded yet.
Try:
App app = new App();
MyWindow wnd = new MyWindow();
app.Run(wnd);

Related

WPF - Unable to shutdown application after adding splash window to the project

I am unable to shutdown my WPF application on closing the main window. Just facing this issue after adding new window (splash screen) to my project.
Below is the newly added code in App.xaml.cs
SplashScreen splash = new SplashScreen();
splash.Show();
MainWindow main = new MainWindow();
this.MainWindow = main;
Thread.Sleep(2000);
splash.Close();
Try to set the Shutdownmode of the App to ShutdownMode.OnMainWindowClose:
ShutdownMode = ShutdownMode.OnMainWindowClose;
Then the app should shutdown when you close main (assuming you actually show it first).

Caliburn Launch without App.xaml, but with bootstrapper

I have a WinForms project from which I want to open a WPF window from a WPF user control project.
But when I create an instance of the WPF window and call Show(), the bootstrapper isn't loaded. In an Windows Application, it's located in the App.xaml, but an user control project doesn't have this.
What can I do?
Thanks!
The only thing accomplished by having the bootstrapper in App.xaml's resources is instantiation of the bootstrapper and keeping a reference so it isn't garbage-collected. You could try making it instantiate like this:
public class SomeClass {
static Bootstrapper _bs = new Bootstrapper();
...
}
That will make sure it's initialized as part of static construction, which happens sometime before you can create an instance of SomeClass. You may have to experiment to see whether that should happen in your UserControl or in your Window.
I have a console application which presents a WPF gui that I made with Caliburn.Micro. I present the GUI like this:
_App = new App();
_App.Run();
Where App.xaml contains the bootstrapper and the main thread is STA like this:
[STAThread]
static int Main(string[] args)
{ ... }
I know your situation is different but maybe this will give you an idea.
Console application test:
Add MaterialDesignColors pakage
[System.STAThreadAttribute()]
static void Main(string[] args)
{
var _app = new App();
_app.InitializeComponent();
_app.Run();
_app.Shutdown();
}

Cannot show up WPF application when setting MainWindow manually and composing application (MEF)

I got my hands om MEF for a week now and I am trying to build up a WPF application that loads imported controls from MEF.
I created a WPF application project and removed the default window and application start up URI. Then I handled the application startup event to compose the application:
public partial class App : Application, IPartImportsSatisfiedNotification
{
{...}
private void App_Startup(object sender, StartupEventArgs e)
{
this.Compose();
}
public void Compose()
{
try
{
globalCatalog.Catalogs.Add(new DirectoryCatalog(extensionsDirectoryPath));
CompositionContainer container = new CompositionContainer(globalCatalog);
container.ComposeParts(this);
}
catch (Exception ex)
{
// Do something
}
}
{...}
}
Actually, when debugging and watching objects after imports are satisfied, everything has hierarchically composed fine like I wanted. But when I try to show up the MainWindow of the application an exception is thrown on MainWindow.Show() call:
"Specified element is already the logical child of another element. Disconnect it first."
Though my code in OnImportsSatisfied method seems fine as it is working when not using MEF mecanism:
public void OnImportsSatisfied()
{
Window mainWindow = new Window();
mainWindow.Content = this.importedControl;
this.MainWindow = mainWindow;
this.MainWindow.Show();
}
I insist on the fact that this works perfectly when not importing controls with MEF. What is surprising is that this code does not work too:
Window mainWindow = new Window();
//mainWindow.Content = this.importedControl;
this.MainWindow = mainWindow;
this.MainWindow.Show();
So I suspect that ComposeParts is doing a bit more than what it says as it is the only member acting on my actual application instance.
Hope someone can help me (Glenn?).
Thanks.
Edit:
I discovered that when I remove the IPartImportsSatisfiedNotification interface from my parts, no exception is thrown and the window shows up. But of course the window is empty as I need this OnImportsSatisfied method to set the DataContext of the window to its associated imported view model.
The sample applications of the WPF Application Framework (WAF) show how to use MEF within a WPF application.
I finally discovered that I was importing my WPF user controls by using the default ImportAttribute constructor, which in fact will make a shared instance of the class if the creation policy is not specified during export. And as many of my controls were implementing the same interface and I was binding them in my views, I was actually trying to add this shared user control instance to different visual elements, which is not permited by WPF (and so the exception).
I marked my imports using the RequiredCreationPolicy set to NonShared and everything got back in order! That was all about learning MEF...

Silverlight without XAML makes source URIs fail?

I'm in the process of removing the XAML from my Silverlight project and making it use only code (as per this article).
Here is my very simple startup event for a Silverlight application (with the standard App.xaml from the template project):
private void Application_Startup(object sender, StartupEventArgs e)
{
Grid grid = new MainPage();
this.RootVisual = grid;
var mediaElement = new MediaElement();
mediaElement.MediaFailed += (s, ea) => { mediaFailed = true; };
mediaElement.Source = new Uri(#"/Content/Some Music.mp3", UriKind.Relative);
grid.Children.Add(mediaElement);
}
Where the MP3 file is set to "Build Action: None, Copy if newer" (ie: it's beside the XAP). Here's the XAML for MainPage:
<Grid x:Class="TestGame.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
</Grid>
And the C# - nothing unusual here at all.
public partial class MainPage : Grid
{
public MainPage()
{
InitializeComponent();
}
}
That all works so far. So my question is this: why is it that when I change
Grid grid = new MainPage();
to
Grid grid = new Grid();
the mediaElement.MediaFailed event gets called (with a AG_E_NETWORK_ERROR)?
The only interesting thing that InitializeComponent is doing is calling Application.LoadComponent (it's the default generated code). So what might that function be doing that allows source URIs to work?
It seems that Application.GetResourceStream still works just fine. But I need to be able to get a few resources external to the XAP.
(Note: it seems this guy is having the same problem - but no one answered his question.)
The key factor is UriKind.Relative. The question is to what is it relative?
One of the effects of LoadComponent is that it shifts the location of "/". Before LoadComponent executes the path "/" refers to the same location as it would do in the host browser. After LoadComponent "/" refers to a hybrid of the root contents of the Xap and the folder that contains the Xap.
Since you are running this via a standalone test html page "/" in your second example refers to the root of the physical drive, e.g. "c:\".
If you change the Url to "Content/Some Music.mp3" (that is remove the "/" prefix) and assuming your test html page is the same folder as the Xap it should work as expected.
Note you can't escape the hybrid path with the parent path "..", Silverlight doesn't let you do that.

Problems with Prism hosted in a WinForm ElementHost

I am having problems with hosting a WPF prism app in an ElementHost control and am desparate for help.
The PRISM app runs fine in silverlight and in a standalone WPF.
The main Shell seems to setup fine in the elementHost on a WinForm however other views only load with the “RegisterViewWithRegion” and not the “Add,Activate” procedure. I need “Add,Activate” for scoping. However I beleive the problem is that I am loading my shell twice … not on purpose. I cannot find a way to call the bootsrapper and set the elementHot without calling “Resolve” twice.
Here is the code for my WinForm and my bootstrapper. Again everything works when using "RegisterViewWithRegion".
Here is the Winform Constructor:
public Form1()
{
InitializeComponent();
if (System.Windows.Application.Current == null)
{
new MyApp();
}
Bootstrapper bootStrapper = new Bootstrapper();
bootStrapper.Run();
var shellElement = bootStrapper.Container.Resolve<ShellContainer>();
//Attach the WPF control to the host
elementHost.Child = shellElement;
}
Here is the bootstrapper:
public class Bootstrapper : UnityBootstrapper
{
protected override DependencyObject CreateShell()
{
return Container.Resolve<ShellContainer>();
}
protected override void InitializeModules()
{
IModule moduleSurvey = Container.Resolve<SurveyModule>();
moduleSurvey.Initialize();
}
}
The Bootstrapper automatically sets Application.Current.MainForm to whatever you returned in the CreateShell method. Hopefully you are setting up an Application (I think that's what you are doing in the first If block). If so, you can just change this:
var shellElement = bootStrapper.Container.Resolve<ShellContainer>();
To this:
var shellElement = Application.Current.MainForm;
That ought to work, but there are definitely some weirdnesses with the ElementHost. We ended up with a lot of strange rendering bugs, especially in a Citrix environment. I don't know if this is a limitation of your setup, but I thought I would mention it.
Good luck!
I had the same GCE (Gross Conceptual Error). I was seeing the same behavior of my views being instantiated twice when using Add or Activate. I was deep into debugging the behaviors when it hit me.
The following is returning a new instance of the ShellContainer.
var shellElement = bootStrapper.Container.Resolve<ShellContainer>();
Either register your ShellContainer type in the container with a ContainerControlledLifetimeManager or put a prublic property on your bootstrapper to access the ShellContainer instance to set into your ElementHost.

Resources