How to provide DataTemplate from a prism module - wpf

I've a WPF application, with Prism, we are using some modules(and more globally, a lot of micro-services).
I'm searching for the best practices to provide to the application a template that could be used to represent a model.
Since I've to do this from a module, I cannot just create a ResourcesDictionary and add it to the App resources.
How would you do this? Our objective is to have a good isolation of features.

I think you've not really fully explained your purpose or what you have here. With that proviso in mind.
If you created a regular resource dictionary in an app you can merge that in app.xaml.
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Dictionary1.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
And you can then target resources in there in markup using x:Key or implicit styling. And templating which targets a datatype.
What that does is add the things in your resource dictionary to a sort of dictionary. ( It's not exactly a dictionary ) It has key and value.
That has scope of your entire application.
You can reference the things in there and switch them out. You can merge another resource dictionary in code. Once they're in there though, they are there to stay until you shut the app down or clear those resources.
You can read a resource dictionary:
ResourceDictionary rd = new ResourceDictionary
{
Source = new Uri("Dictionary1.xaml", UriKind.Relative)
};
And merge it:
Application.Current.Resources.MergedDictionaries.Add(rd);
If you merge a resource dictionary in markup, it doesn't even have to be compiled. I never tried that in code but I guess you might well find you could merge a "loose" uncompiled resource dictionary. If it didn't work directly you could definitely xamlreader.Load or .Parse an uncompiled rd into one in memory.
That adds to application scope. If you wanted that then maybe you ought to just merge your resource dictionaries in app.xaml though.
If you want scope, then windows, usercontrols etc etc all have resources. You can merge a resource dictionary in at pretty much any level you fancy and it'll then have a narrower scope than application.

Related

WPF Load resources via PRISM

I have a WPF application that is being written using PRISM. I want a way to allow it to be "re-branded" easily. So I started to create a module, that when initialized added resource dictionaries to the application. This worked until I wanted to style some of the components directly in the shell.xaml. The module is not initialized when the xaml is parsed so it errors.
I know I could reference a resource using the application:/// syntax but that then forces the styling dll to be named a specific name, which I am not fond of.
Does anyone have any other suggestions?
This answer is waaaay after the fact but it is what I'm planning for my current project, using MEF. It does not have to be a module.
This is the interface
[InheritedImport]
public interface IBrandProvider
{
ResourceDictionary ProvideResources();
}
Implementations will load a resource dictionary using the pack URI syntax that you already alluded to. Implementation on your shell might look like this;
[ImportingConstructor]
public MainWindow(IBrandProvider brand)
{
this.Resources.MergedDictionaries.Add(brand.ProvideResources());
}
Ensure that your IBrandProvider is in your Container (Unity or MEF) and make sure you use it somewhere. BOOM, you are good to go. As you might expect, this is not possible or even desirable in XAML.
For extra flavour, the interface could return a value stating what level you want the resources automatically applied - application, shell or none (with a key so you can cherry pick them later perhaps).

Why are XAML namespaces URIs and what are they for?

I am skeptical regarding the XML namespaces. I don't know why we need these namespaces in all XAML applications.
xmlns=http://schemas.microsoft.com/winfx/2006/xaml/presentation
xmlns:x=http://schemas.microsoft.com/winfx/2006/xaml
I understand the concept of namespaces as in System.Text, System.LINQ, etc. We use that in our classes because we have class libraries that sit on the same computer.
Questions:
It represents some URI. So WPF is standalone application. If the user of the app is not connected to Internet, whats the significance of it? First of all why do we need this?
What's the difference between the first and second line? What does xmlns:x represent?
Also, I see this error upon trying to access that URI
An error occurred while processing your request
What does this mean?
A XAML-namespace is just like a namespace in C++ or C#/VB.NET, it serves the purpose of logically grouping classes and other items.
In WPF/XAML you have a namespace xmlns=http://... which is the namespace for the controls WPF offers you by default. xmlns:x is a namespace to provide some special values like x:Null to represent a null-value.
You can define your own controls and name them TextBox, too, but you should create an own namespace for these in order to not interfer with the global namespace.
The URLs mentioned in the definitions of the namespaces have nothing to do with actual internet-connection or real existing URLs, this is just, the namespaces can be properly distinguished.
There is a nice article on MSDN about this topic.
It's the way those namespaces were named. That's all. You should not treat them as uri.
As for xmlns vs xmlns:x - the first one is the default namespace, which contains wpf controls, the second one is namespace whcih contains some additional declarations (x:Type, x:Name, etc).
I know it is an old thread but I think the information provided in answer is not totally correct. The url which you see is not a namespace but a collection of namespaces grouped into one. Below are some of the namespaces from .net which are mapped by default namespace (url)
System.Windows, System.Windows.Automation, System.Windows.Controls, System.Windows.Controls.Primitives, System.Windows.Data, System.Windows.Documents

What are xmlns=[some url] attributes in the beginning of WPF xaml files for?

I noticed in the beginning of a xaml we have stuff like
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
The only other usage I see for xmlns is importing namespaces from my assemblies. Are these also instances of importing assembly? From a URL? If not, what do they refer to? What if the computer is not connected to the internet?
this is not related to xaml, but to xml in general.
The target of namespaces is to be able to uniquely identify xml objects.
take a look here.
For example, it allows to have two "Customer" node, with different namespaces. Programs can then distinguish if it's a customer node from system A or system B.
This can be compared to C# namespaces also. The "Control" class exists both in System.Windows and System.Windows.Forms and even in System.Web.Ui... same name, but "ownership" are different according the namespaces.
One thing to know, it's only a declaration. the namespace is a freetext, the http:// format is just a convention, and no download of the target uri will occur.
The first declaration maps the overall WPF client / framework XAML namespace as the default:
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
The second declaration maps a separate XAML namespace, mapping it (typically) to the x: prefix.
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
The relationship between these declarations is that the x: prefix mapping supports the intrinsics that are part of the XAML language definition, and WPF is one implementation that uses XAML as a language and defines a vocabulary of its objects for XAML. Because the WPF vocabulary's usages will be far more common than the XAML intrinsics usages, the WPF vocabulary is mapped as the default.
The x: prefix convention for mapping the XAML language intrinsics support is followed by project templates, sample code, and the documentation of language features within this SDK. The XAML namespace defines many commonly-used features that are necessary even for basic WPF applications. For instance, in order to join any code-behind to a XAML file through a partial class, you must name that class as the x:Class attribute in the root element of the relevant XAML file. Or, any element as defined in a XAML page that you wish to access as a keyed resource should have the x:Key attribute set on the element in question
http://msdn.microsoft.com/en-us/library/ms747086.aspx

Why can't I use the Name attribute on UserControl in the same assembly?

When I created a WPF UserControl and tried to use it, I got the following compiler error:
Because 'UserControl1' is implemented in the same assembly, you must set the x:Name attribute rather than the Name attribute.
The message is clear on what to do to fix it, but what is its cause? Why can't I use Name here?
x:Name is simply a more explicit way of saying "The name attribute in this specific XML namespace". The fact that WPF can't compile it without being given this hint because it's in the same assembly is just a limitation of how they wrote the parser.
If you are asking why it is this way, I do not know for sure because I didn't write it. It probably has something to do with it needing to be able to resolve the Name attribute (read: Dependency Property) to something concrete BEFORE building your UserControl1, in other words, a catch-22.
In the beginning the XAML compiler was written to enable to creation of “trees” of .net objects, there were 101 projects within Microsoft that used XAML. The XAML compiler does not know anything about WPF.
The “Name” property is defined by WPF and is not known about by the XAML compiler. WPF maps the name property to be the same as the “Name TAG” that is supported by the XAML compiler. The “x” in “x:name” is saying use “name” as defined by the XAML xml schema, “Name” says find a property called “name” on the given object. See In WPF, what are the differences between the x:Name and Name attributes? for more details.
The XAML compiler is very limited in what it can do with a user control without having to load the assembly that defines the user control. As the XAML needs to be compiled before the assembly can be loaded, the xaml compiler clearly can’t load the assembly for a control that is implemented in the same assembly. Therefore the XAML compiler does not even know the item is a user control.
Properties that are defined on a user control (or its parent class) can therefore not be accessed. “Name” is a property that is defined in the parent (or super-parent) of a custom control.
The XAML compiler could just say “Name is not defined as a property”; if it did, think about how many people will fail to get a simple custom control working! Therefore the XAML compiler has a special case that gives a more useful error message, by “guessing” what the code means. Its guess are mostly correct.
Anything apart from the most simple user control needs to be in its own assembly, however user simple control are so common that a special case was considered worthwhile for them.

What does the runtime do with XAML namespaces?

In every XAML document, there are one or more namespace declarations. ie:
<Window x:Class="WindowsApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1 Height="300">
The declarations are in the form of a URL, leading me to ask: Does the runtime actually retrieve information from those URLs when the application loads? What happens if no Internet connection is present?
This is just a standqard xml namespace and nothing special to do with XAML at all. It is really just a unique identifier for this particular xml; no data is retrieved from this url and, in fact, it doesn't even need to be a url.
See this previous post for an explanation of what a namespace is in xml, and why the actual namespace text itself is of no real consequence.
No. The runtime does not dereference the URIs, they are just used as readable globally unique identifiers. The fact that they use an http protocol at all is just a convention. They follow the XML Namespace standard from W3C.
The URIs refer to the URIs defined using the XmlnsDefinitionAttribute defintions in the WPF assemblies. The XAML reader uses these attributes to group CLR namespaces from those assemblies together into a combined XML namespace.

Resources