How efficient is XAML parsing in WinRT / Win8? - xaml

When creating UserControls, it looks like the XAML is being parsed every time the control is initialized.
For example, when I create a UserControl, there's auto-generated code to initialize the component that looks like this:
public void InitializeComponent()
{
if (_contentLoaded)
return;
_contentLoaded = true;
global::Windows.UI.Xaml.Application.LoadComponent(this, new global::System.Uri("ms-appx:///Views/MyView.xaml"), global::Windows.UI.Xaml.Controls.Primitives.ComponentResourceLocation.Application);
}
This existed in Silverlight as well.
Creating the control once or twice is not a big deal, but if I have a large visual tree in each UserControl with Visual-States and bindings, and I'm creating it many times per application lifecycle, it would make sense to build the visual controls using C# to boost performance.
So, my question is:
Does the parser/framework "remember" the XAML file and avoid re-parsing it again on subsequent calls? That is, does it create a binary representation of the XAML so it doesn't have to read text all over again?

It's my understanding that XAML gets compiled into a binary form as a resource within your application. The runtime does not have to parse the text of the .xaml file, just as it does not have to parse your .cs code files.
The performance of instantiating the classes as declared with XAML is supposed to be on par with creating it in code.

Windows 8.1 xaml finally added XAML binary format :)
XAML Binary Format: The final signed appx will no longer contain text based markup as it will get converted into Binary.

Related

How do I provide a custom data as a DataProvider for ImageTilesLayer on a mapControl in XAML file?

How do I provide a custom data as a DataProvider for ImageTilesLayer on a mapControl in XAML file?
I am new to WPF and DevExpress. I was trying a few examples given in the DevExpress documentation site.
Link: How to Load Image Tiles from Another Source
In the example, How to Load Image Tiles from Another Source given in their site, the DataProvider for a ImageTilesLayer is assigned in the code behind file.
Is it possible to mention the same DataProvider in the XAML instead of the code behind file?
You can assign the ImageTilesLayer.DataProvider property in XAML as follows:
<dxc:MapControl>
<dxc:ImageTilesLayer>
<dxc:ImageTilesLayer.DataProvider>
<local:CustomMapDataProvider/>
</dxc:ImageTilesLayer.DataProvider>
</dxc:ImageTilesLayer>
</dxc:MapControl>
P.S.
For more information about XAML properties syntax, see XAML Overview (WPF)-> Property Element Syntax MSDN article.
For more information about custom types in XAML, see XAML and Custom Classes for WPF.
Coding Horror, I would suggest you first read the tutorials given by DevExpress.
Link to the tutorials is below.
https://documentation.devexpress.com/#WPF/CustomDocument10682
It explains the different layers on map control.
Once you have read that, read on how to load images from different source
https://documentation.devexpress.com/#wpf/CustomDocument11174
In the code, instead of giving a url, change it to a local image folder where you have cached all the map tiles.
public class CustomTileSource : MapTileSourceBase {
const string roadUrlTemplate =
#"http://{subdomain}.tile.openstreetmap.org/{tileLevel}/{tileX}/{tileY}.png";
You can know more about caching at https://documentation.devexpress.com/#WPF/CustomDocument12205

How to view the procedural code for any xaml file

I'm working in Visual Studio 2012 with xaml to create an application. When I make a new solution and WPF project and look at the xaml in the application file, I see xmlns, a startupuri, and a tag for application.resources.
When I want to see the code-behind that these tags are creating, I have only the .cs file with maybe a few things in it and the mysterious InitializeComponent() that performs all of the parsing. Here's an example of what it looks like:
public partial class MainWindow : Window //This is generated with a wpf project.
{
public MainWindow()
{
InitializeComponent();
}
}
If possible, how can I view the procedurally generated code that InitializeComponent is creating?
I don't think that the complete xaml source gets compiled into .g.cs files.
Quoting this codeproject article:
When you compile a WPF application in Visual Studio it will compile your XAML files into a compressed representation known as Binary Application Markup Language (BAML). The BAML is then saved as a resource in the resultant assembly. When that assembly is loaded and the resource is requested, the BAML is streamed out and very quickly turned into the object graph described by the original XAML.
In the project directory, under the obj and Debug folders should be files labeled .g.cs that correspond to existing files. Presumably, these are Generated C-Sharp files that contain the generated code that I was looking for.

Loading Loose Xaml with custom controls on WinRT fails unless dummy DataTemplate exists

In ReactiveUI, I run this code at a certain point:
const string template = "<DataTemplate xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation' xmlns:routing='using:ReactiveUI.Routing'>" +
"<routing:ViewModelViewHost ViewModel=\"{Binding}\" VerticalContentAlignment=\"Stretch\" HorizontalContentAlignment=\"Stretch\" IsTabStop=\"False\" />" +
"</DataTemplate>";
var theTemplate = XamlReader.Load(template);
On other platforms, this works great (the xmlns declaration is different of course), but on {WinRT / Metro / Windows Store}, this throws an Unspecified Error:
WinRT information: The type 'ViewModelViewHost' was not found. [Line: 1 Position: 253]
The Twist
However, if you include a dummy resource on the page:
<Page.Resources>
<DataTemplate x:Name="Foo">
<routing:ViewModelViewHost ViewModel="{Binding}" />
</DataTemplate>
</Page.Resources>
...then it works! What gives?
The "twist" makes me think this must be because the application does not have correct XAML metadata for the type being instantiated - rather than using reflection to resolve types in XAML files like WPF/Silverlight, WinRT uses code generation to resolve via the IXamlMetadataProvider interface (there's a decent description here; this sounds like what you're doing, see also the followup). Adding the reference forces this metadata code to be generated properly. If this is the case, you should be able to achieve the same effect by simply adding the type itself to the resources under some unused key, without the data template.
Have a look in your application's "obj" directory, Visual Studio generates a XamlTypeInfo.g.cs file to implement IXamlMetadataProvider. This should contain an entry for the type that is failing - in the case where you have added a dummy reference, there should be full details required to instantiate the type. Without this, I've found it's possible to have some reference to type type, but insufficient information - however this prevents the fallthrough behaviour (looking up the type in a dependent DLL which might have a custom metadata provider).
Other than adding a dummy reference to the library type in the final application itself, the only solution I found for this is to apply the Bindable attribute to the type. While this is supposed to relate to C++, I found this can be used in C# to force a type to always appear in the code generated for XAML type metadata.

Resource localization: use of x:Uid referring to another assembly's resource

I am writing a win8 application and will be using the built-in resource management system: resw file and x:Uid tags in my XAML code.
So I create let's say a TextBox like that:
<TextBlock Style="{StaticResource HeaderTextStyle}" x:Uid="ResourceTest"/>
I create the corresponding resource file in my assembly with a ResourceTest.Text entry and it works fine: proper text is displayed at runtime.
Now, I would like to move all my resx files to another C# Library for maintainability. So I put the resources file in a brand new project and reference this new assembly from the main assembly.
But this causes the previous construct to fail (no text is displayed).
However, if I programmatically retrieve the resource value using the following code from inside the side assembly (called ResourcesLibrary), I get the string correctly:
static ResourceLoader resourceLoader = null;
public static string GetString(string resourceName)
{
if (resourceLoader == null)
resourceLoader = new ResourceLoader ("ResourcesLibrary/Resources");
return resourceLoader.GetString (resourceName);
}
How do I enable the x:Uid mechanism when dealing with out-of-assembly resources?
I tried a few things in the x:Uid such as ResourcesLibrary/Resources/ResourceTest but with no luck.
I had the same problem for a long time. But after testing a little bit, I solved it by writing the whole Path of the Resources in the XAML Code.
Something like this:
<TextBlock x:Uid="/ResourcesLibrary/Resources/ResourceTest" />
Unfortunately this answer came very late, but may it can help other persons.
As per my understanding you can't use x:Uid if the resources are maintained in a .resx file.
if you use .resw files you can access the strings whatever the assembly they are residing in.
they can be accessed as you mentioned in your question like this "ResourcesLibrary/Resources/ResourceTest"

How to add at run-time component (Compact Framework 3.5)?

I need to add at run-time component of the PictureBox.
There will be a few to several. How can I do it?
Programmers writing based on the Compact Framework 3.5.
You would do it the same way that all controls are added. In general it looks like this:
var newControl = new Control(); // or new PictureBox
// initialize properties like size, position, etc
myForm.Controls.Add(newControl);
A good way to see how this is done for different controls is to look at the designer-created conde for InitializeComponents, as it creates all of the controls and layout done in the designers at run time.