Resource not loaded with PrismApplication (Prism v7 - 7.0.0.329-ci) - wpf

Using the new Prism v7 library, the Bootstrapper class is obsolete and must be replaced by the PrismApplication class.
I configured the new PrismApplication for my app but the app failed to load the XAML resources at the right time.
I declare a few resources in the App.xaml file:
<local:MyPrismApplication x:Class="Xxx.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Xxx">
<local:MyPrismApplication.Resources>
...
</local:MyPrismApplication.Resources>
</local:MyPrismApplication>
The new PrismApplication creates the Shell. The Shell need resources that aren't yet loaded.
Using the 'old' bootstrapper class, the problem doesn't exist.
What is recommended with the new PrismApplication class? Can we not set up anymore the resources in the App.xaml ?

Actually, you may have found a bug. I changed the startup process to start in the Ctor, not in the OnStartup override. I should probably change it back to do everything in OnStartup instead, similar to the bootstrapper. This will ensure all resources are available. Can you submit a bug on the GitHub site?
https://github.com/prismlibrary/prism/issues
EDIT: Just updated the PrismApplication class. Try the latest CI build and see if it works.

Related

Create WPF BrowserView defined in XAML with custom BrowserContext

I've got a DotNetBrowser instance defined in a XAML file
<Grid>
<wpf:WPFBrowserView x:Name="BrowserView"></wpf:WPFBrowserView>
</Grid>
The application is used by multiple people, which is causing issues due to the issue discussed here:
Chromium profile directory is already used/locked by another browser
Is it possible to use XAML to define the browser control and still assign a custom context to the browser instance?
Is it possible to use XAML to define the browser control and still assign a custom context to the browser instance?
No, I am afraid it's not.
The Browser property of the WPFBrowserView class doesn't have a public setter so you must create the custom Browser and the BrowserContext programmatically:
BrowserContextParams params1 = new BrowserContextParams("C:\\my-data1");
BrowserContext context1 = new BrowserContext(params1);
Browser browser1 = BrowserFactory.Create(context1);
XAML doesn't support anything like calling BrowserFactory.Create(context1).
Unfortunately, the custom BrowserContext can be configured only if the Browser and WPFBrowserView were created from the source code.
The possible approach is to wrap WPFBrowserView and its non-default initialization into a custom control that manages instantiating and disposal of the WPFBrowserView, make this control expose all the necessary properties and then insert it into your XAML.

how to set startup uri property to another window in folder in wpf project

In my wpf project i have created a folder called practice, in that folder i added a window, now i want to run that window, so in app.xaml file i set the startup uri to foldername.window.xaml but it is saying build action property is not set to resource.
for that i setted build action property to resource. Now this time that it is showing error message initialized componenet doesn't exist in the current context.
Can you tell me what properties we need to set when we create separate folders in wpf project and that folders contains windows or pages. and How to access those pages in other pages or in App.Xaml file startupUri Property.
When you have folders in your project structure, you should use a "/" not a ".", so it's foldername/window.xaml.
(I hope it's not actually called window.xaml by the way. That's a confusing name for a type in a WPF project, because there's a built in type called Window.)
Setting the build action to Resource will make matters worse: not only were you using the wrong name, you've now changed the build action to the wrong one for XAML. The correct build action for a .xaml file is usually Page. (App.xaml is an exception to that rule.) The Page build action causes the page to be compiled into a binary representation (known as BAML), and that binary format can then be loaded either by the call to InitializeComponent in the codebehind, or through Application.LoadComponent.
Setting the build action to Resource will just embed a copy of the XAML source directly in the project, which won't help you - you can't work with XAML in that form if you want to have a codebehind file. (Not in WPF, anyway. It's different in other XAML-based frameworks such as WinRT.)
Since Page is the default build action for a newly-added window, you don't actually need to set any properties at all. You just need to use / for folder boundaries.
If the XAML is inside any Folder the startup url will be defined as below.
This is how it will defined.

Integrate an MVVM WPF Solution with Caliburn Micro and MEF into an old WPF Applicaion with codbehind and Page Navigation

Last year I built a WPF application using page navigation and no MVVM.
Recently I was asked to build a new application for the same customer which I did in WPF MVVM with Caliburn Micro and MEF. Now my customer asks me to integrate the new application into the old one.
My thought was to add a new page to the old application and to integrate the shell of the new application into a ContentControl of this page.
My problem now is that the old application is started by an
<StartupUri="Views\NavWindow.xaml">
entry in the app.xaml, while the new application is started by a bootstrapper like
<local:AppBootstrapper x:Key="bootstrapper" />
where AppBootstrapper looks like
class AppBootstrapper : Bootstrapper<ShellViewModel>
{
private CompositionContainer container;
protected override void Configure()
{
container = new CompositionContainer(new AggregateCatalog(AssemblySource.Instance.Select(x => new AssemblyCatalog(x)).OfType<ComposablePartCatalog>()));
CompositionBatch batch = new CompositionBatch();
batch.AddExportedValue<IWindowManager>(new WindowManager());
batch.AddExportedValue<IEventAggregator>(new EventAggregator());
batch.AddExportedValue(container);
container.Compose(batch);
}
protected override object GetInstance(Type serviceType, string key)
{
string contract = string.IsNullOrEmpty(key) ? AttributedModelServices.GetContractName(serviceType) : key;
var exports = container.GetExportedValues<object>(contract);
if (exports.Count() > 0)
{
return exports.First();
}
throw new Exception(string.Format("Could not locate any instances of contract {0}.", contract));
}
}
So, as far as I understand, in case of the new app the bootstrapper initializes the whole app, calls the ShellViewModel and eventually the ShellView.
Because I use the EventAggregator in the new app to send messages from one viewmodel to another, I think I canĀ“t just get rid of the bootstrapper and use the view-first model of Caliburn Micro.
So my problem is: can I call the bootstrapper from my old app by myself, and if so, where should I store the instance of it, and how do I tell Caliburn Micro where to put the ShellView?
Any help is appreciated.
CM is so light that in these situations it's actually worth having a peek at the source to see what a particular class is actually doing.
The Bootstrapper works because declaring it in the resources file of the application forces an instantiation of it. The constructor calls Start on the instance and that sets up the aggregator, IOC, etc.
https://caliburnmicro.codeplex.com/SourceControl/changeset/view/4de6f2a26b21#src/Caliburn.Micro.Silverlight/Bootstrapper.cs
If you were to load the application into a ContentControl in another application, I can't see a reason why it wouldn't kick off CM as the resources for the loaded application would still be processed, instantiating and starting up the Bootstrapper etc. Have you tried it in a test project? That might be your first option.
There may be some areas where CMs default implementation of Bootstrapper might not be ideal, but on first glance I can't see any glaring issues (not sure what happens to the application events such as OnStartup etc when you load a sub-application so you might want to look at that). Worst case you can roll your own Bootstrapper for the sub-app and just rebuild with the tweaked functionality.

Can't get pack Uri to work

I've got a WPF application I'm building. The solution contains a WPF control library project called CustomControls. There's a folder under the CustomControls project folder called Layouts. There's an XML file in that folder called OnscreenLayout.xml. The Build Action property for this file is set to Embedded Resource.
I'm trying to load that file into a stream in the code behind and pass the stream on to a method of a third party library class. The code in question looks like this:
OnscreenKeyboard.DefaultLayout = FPS.VirtualKeyboard.KeyboardLayout.Create(
App.GetResourceStream(
new Uri( #"/CustomControls;component/Layouts/OnscreenLayout.xml",
UriKind.Relative ) ).Stream );
When this code runs, it throws an IOException with the message
Cannot locate resource 'layouts/onscreenlayout.xml'.
I've even tried using this string for the Uri:
#"pack://application:,,,/CustomControls;component/Layouts/OnscreenLayout.xml"
But no joy. What am I doing wrong?
Edit: I have even tried changing the build action for the file from "Embedded Resource" to "Resource" and it still doesn't work.
Thanks
Tony
Only Content and Resource build actions are valid for resource files used in WPF application.
Please avoid other build actions such as Embedded Resource - this will work as well with appropriate API, but it is not favored by WPF.

Dynamic loading of modules in Silverlight using Prism and Unity

The basic idea that I'm trying to accomplish is to configure my Silverlight app to resolve its dependencies at runtime (without having to add references to dependent DLLs in the project).
I have my UI project that references an infrastructure project than contains various interfaces (e.g. repositories). Concrete implementations of these interfaces are stored in separate SL apps that I want to download and link to at runtime. I want to be able to configure my UI app from an external config file so that I can switch from one interface implementation to another at runtime without having to recompile the app.
What I have done so far is to create a Prism module for each implementation (in a separate SL app) and get those XAPs hosted in my web project. In my UI app I created a boostraper that has this:
protected override IModuleCatalog CreateModuleCatalog()
{
var mc = Microsoft.Practices.Prism.Modularity.ModuleCatalog.CreateFromXaml(new Uri("/UI;component/Repositories/ModulesCatalog.xaml", UriKind.Relative));
return mc;
}
ModulesCatalog.xaml looks like this:
<Modularity:ModuleCatalog xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
xmlns:Modularity="clr-namespace:Microsoft.Practices.Prism.Modularity;assembly=Microsoft.Practices.Prism">
<Modularity:ModuleInfo Ref="ImplementationOne.xap"
ModuleName="ImplementationOne"
ModuleType="ImplementationOne.Module, ImplementationOne, Version=1.0.0.0" />
</Modularity:ModuleCatalog>
In my ConfigureContainer override I have:
protected override void ConfigureContainer()
{
var unity = Unity.CreateFromXaml(new Uri("/UI;component/Repositories/UnityConfiguration.xaml", UriKind.Relative));
unity.Containers.Default.Configure(Container);
Container.RegisterInstance<Unity>(Unity.ConfigurationKey, unity);
base.ConfigureContainer();
}
But the unity.Containers.Default.Configure(Container) throws that the assembly cannot be found. (If I manually add the DLL to UI.xap file this works so I guess I'm missing something as the XAP is either not being downloaded or the assembly is not getting registered).
I've been struggling with this for a week now, read lots of SO topics but still cannot solve the problem. All the examples that I have found contain direct project refrences which is exactly what I'm trying to avoid.
Thanks!
To do assembly discovery and dynamic XAP loading you should use MEF container, not Unity.
See more information from official source: http://msdn.microsoft.com/en-us/library/ff921140(v=PandP.40).aspx

Resources