is there a possibility in WPF / XAML to eager load resource dictionaries? I have a resource dictionary defined in my XAML:
<s:SurfaceWindow.Resources>
<local:SomeConverter x:Key="SomeConverter"/>
<local:SomeView x:Key="SomeView" />
</s:SurfaceWindow.Resources>
I need these resources before the loaded event occurs - is there any way to do that?
Thanks
If you place you ResourceDictionaries BEFORE you create the control then you should be fine. If you are REALLY eager then put your Resources in the App.xaml file
Related
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.
AB.xaml MergedDictionaries A.xaml and B.xaml
CD.xaml MergedDictionaries C.xaml and D.xaml
BaseStyle.xaml MergedDictionaries AB.xaml and CD.xaml
app.xaml MergedDictionaries BaseStyle.xaml
suppose that i have a brush defined in A.xaml, and in C.xaml use the brush.
application has merged the AB.xaml first,and then CD.xaml, but the question is that why C.xmal can not access the brush resource when runing the application using StaticResource keyword.
Of course, DynamicResource keyword work fine.
And if app.xaml directly Merged AB.xaml and CD.xaml, also work fine.
so what is the different?
finally i find the reason:
Visit https://stackoverflow.com/a/2679228/2325995
MSDN: Resources in a merged dictionary occupy a location in the resource lookup scope that is just after the scope of the main resource dictionary they are merged into.
I'm having a little problem with Merging dictionaries in my WP7 application, The app contains a lot of pages and the loading time exceeded the market place limit which is 5 seconds, I had to put the majority of the pages and UI stuff in a separate class library to cut off the loading time, the problem is that the pages ware referencing static resources in the global app.xaml, I tried to move the xaml stuff in App.xaml to a separate resource dictionary in the class library project. I also referenced that resource dictionary file in every page.
<phone:PhoneApplicationPage.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Resources.xaml" />
</ResourceDictionary.MergedDictionaries>
<Converters:TimeSpanToWeekAndDayConverter x:Key="weekAndDayConverter"/>
</ResourceDictionary>
</phone:PhoneApplicationPage.Resources>
The problem is that I always receive this exception :
Failed to assign to property 'System.Windows.ResourceDictionary.Source'.
I also tried to change the build action of that resource dictionary from Page to Resource to Content (With all their specific path syntax considerations) without any luck.
I hope someone has a idea.
Thanks
I don't think you need to move the resources - you can keep them in the App resources. It should work.
You need to reference the dictionary by using the full name. In this case:
Source="/AssemblyName;component/Resources.xaml"
Otherwise, it won't know how to find it.
This question involves the Visual Studio (2008) WPF Designer's apparent inability to handle the usage of resources located at the App.xaml level if the App.xaml is in a separate assembly from the view.
To simplify the explanation of the problem I have created a test application. This application has two assemblies: View and Start. The View assembly contains a xaml window called Window1, and the Start assembly includes the App.xaml file. The App.xaml file in the Start assembly has its StartupUri set to the Window1 in the View assembly. Neither of these files have code-behinds (aside from the standard constructors and InitializeComponent() call).
The code for this example is as follows:
App.xaml:
<Application x:Class="Start.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="pack://application:,,,/View;component/Window1.xaml"
>
<Application.Resources>
<!-- Warning Text Style -->
<Style x:Key="WarningTextStyle" TargetType="TextBlock">
<Setter Property="FontWeight" Value="Bold" />
</Style>
</Application.Resources>
Window1.xaml:
<Window x:Class="View.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1"
Height="300"
Width="300"
>
<Grid>
<TextBlock Text="This is test text" Style="{StaticResource WarningTextStyle}" />
</Grid>
</Window>
The Window1.xaml file contains a single TextBlock that references the App-level WarningTextStyle. This code works fine at runtime because the Window properly finds the App-level resource; however, at design-time the designer complains that it cannot find the WarningTextStyle.
Does anybody know of a clean and scalable solution to this problem?
My standard approach with large applications is to organize my app-level resources into resource dictionary files, and then merge those dictionaries in the App.xaml. To work around the problem that I've described above I have to merge those resource dictionaries into each view's resources. This seems very inefficient, and if I later add another resource dictionary then I need to merge that new dictionary into every view.
A silver bullet solution would re-direct the designer to find the app-level resources. A reasonable work around would be the merging of the app-level resource dictionaries into each view, but only at design-time. At runtime I would like to avoid merging these dictionaries in every view because of the efficiency issues.
I've tried merging the dictionaries on each view in the view's code-behind constructor, and then wrapping that logic in an if statement that checks the DesignerProperties.GetIsInDesignMode() method; however, the Visual Studio designer does not run the view's constructor - so this approach appears to be a bust.
Does anybody have a better solution or work around?
Can you merge the resource dictionary in your referenced assembly (be it App.xaml or your own resource dictionary) from your main (exe) assembly's App.xaml?
I just had a different idea: use a DynamicResource instead of a Static one. This might introduce a tiny performance hit, but I doubt it would be measurable.
I'm working on a wpf application, and up until recently, I had a ResourceDictionary inside my main window's resources part of the xaml. The resource dictionary contained an DataTemplate that was used to style several listboxes in the window. The xaml for this datatemplate contained pointers to event handlers, eg:
<Button n:Name="btnClickMe" Content="Click Me!" LeftMouseButtonUp="btnClickMe_Click" />
I recently decided to split the content of the window up into separate user controls, and to move my ResourceDictionary into it's own file. But, of course, there isn't a code-behind file for a resource dictionary file. How can I wire this up, with things split up as I've described?
Thanks in advance!
You can add a code-behind to a ResourceDictionary; just make sure your class names are referenced correctly. For instance, in the ResourceDictionary if you were working with AppStyles.xaml the XAML file would have a class of:
x:Class="Client.App.Shell.themes.AppStyles"
In the code-behind, AppStyles.xaml.cs, you would make sure to have the class:
namespace Client.App.Shell.themes
{
public partial class AppStyles
...
You can add a new class and name it with the same name as your resource dictionary plus the .cs extension and Visual Studio will automatically set things up so it becomes the code behind file.
For example if you have a resource dictionary called Buttons.xaml, add a file called Buttons.xaml.cs.
You should consider using RoutedCommands, I am thinking.
there are many many resources online, here are a couple that might help you.
http://msdn.microsoft.com/en-us/library/ms752308.aspx
http://www.devx.com/DevX/Article/37893/0/page/1