ResourceDictionary in wpf as dll application - c#

Let's start from the beggining. I have an app in wpf which uses my custom window style. I'm defining this custom style in app.xaml like below:
<Application x:Class="GeoLocations.Test.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="MainWindow.xaml">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="ThemedWindowStyle.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
Nowadays there came a requirement that i need to build this application as dll and later on call it from Windows.Forms application. Obviously the app.xaml code is not being fired since this is not start up application anymore. Is there any way to load it ?
I tried to manually register this Dictionary in code behind but with no success. I also tried to change Build Action from "Page" to "Content" and "Do not copy" to "Copy if newer" but it is giving me different exception:
'Failed to create a 'Type' from the text 'local:ThemedWindow" with inner exception "{"Type reference cannot find type named '{clr-namespace:GeoLocations.Test}ThemedWindow'."}
(this exception is beeing fired inside ResourceDictionary so it's loaded but why it can't find the type ?).
ThemedWindow is a type which inherits from Window and later on all my windows inherits from ThemedWindow instead of Window
I have no idea how to solve this issue. Anyone got some knowledge to help ?

Ok, so i resolved this be adding my ResourceDictionary in code behind in my ThemedWindow Constructor. Like below:
var rd = new ResourceDictionary();
rd.Source = new Uri("pack://application:,,,/GeoLocations Screens;component/ThemedWindowStyle.xaml");
Resources.MergedDictionaries.Add(rd);

Related

C# WPF: The Resource Dictionary does not load at run time, but displays correctly in the designer

Problem: The resource dictionary does not load at run time, but displays correctly in the designer. If I change the color in Dark.xaml to green, I can notice in the designer that my Window background (Layout.xaml) turns green. but when I compile the project in Debug mode, the background is just transparent !!
What I have tried in App.xaml:
<Applicationxmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:StackOverflow" x:Class="StackOverflow.App">
<Application.Resources>
<ResourceDictionary Source="#"/>
</Application.Resources>
</Application>
And:
<Applicationxmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:StackOverflow" x:Class="StackOverflow.App">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="#"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
In the source value, I tried these 3 possibilities:
Theme/Dark.xaml
/StackOverflow;component/Theme/Dark.xaml
pack://application:,,,/StackOverflow;component/Theme/Dark.xaml
App.xaml.cs:
Current.ShutdownMode = ShutdownMode.OnExplicitShutdown;
Window Window = Server.Status() is StatusCode.OK ? new Layout() : new Login();
Window.ShowDialog();
Current.Shutdown();
Dark.xaml:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Class="StackOverflow.Theme.Dark" xmlns:local="clr-namespace:StackOverflow.Theme">
<SolidColorBrush x:Key="Layout.Background">Red</SolidColorBrush>
</ResourceDictionary>
Dark.xaml: File Properties
Build Action: Page
Copy to Output Directory: Do not copy
Custom Tool: XamlIntelliSenseFileGenerator
Custom Tool Namespace:
Dark.cs:
namespace StackOverflow.Theme {
public partial class Dark : ResourceDictionary {
public Dark(){
InitializeComponent();
}
}
}
Dark.cs: File Properties
Build Action: Compile
Copy to Output Directory: Do not copy
Custom Tool:
Custom Tool Namespace:
Note: These two files (Dark.xaml / Dark.cs) are nested using the File Nesting extension (Keith Wilson).
Layout.xaml:
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:StackOverflow.XAML"
x:Class="StackOverflow.XAML.Layout"
Background="{DynamicResource Layout.Background}"
AllowsTransparency="True"/>
Project File Structure:
XAML
Layout.xaml
Theme
Dark.xaml
App.xaml
Other information:
Solution Configuration: Debug
Solution Platform: x64
Microsoft Visual Studio Community 2019 v16.7.3
Update:
For some reason the problem reappeared with the Application StartUpUri, if you noticed that I didn't use this attribute because I have to verify the user's login before giving them access to the main window. So behind the code in App.xaml.cs I call Login.ShowDialog() and Layout.ShowDialog(). After setting this attribute to Layout Window, I can notice that the application is consuming the resources defined under Dark.cs, so if I change this line:
<SolidColorBrush x:Key="Layout.Background">​​Lime</SolidColorBrush>
The layout background changed at runtime to the color Lime, but I'm wondering if it is possible to use the same resources defined in App.xaml in all project windows, in my case StartUpUri will be Login.xaml, and under Login if the user info is correct I can prevent this window from showing and show my layout window. but the question here is whether this resource named "Layout.Background" can be used in both windows?
I got the idea that the app resource dictionary defined in App.xaml is like a super global resource, which I can use whenever I want. Is it correct? because this result does not seem to support it.

Merged ResourceDictionary initalization in UWP app

During development of my UWP app I have noticed and intersting oddity which I have hard time explaining.
I user MvvmLight and I decided to add the ViewModelLocator resource instance in a separate ResourceDictionary Core.xaml which will be referenced from MergedDictionaries in App.xaml.
Following is the content of App.xaml:
<Application ...>
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Resources/Core.xaml" />
<ResourceDictionary Source="Resources/Converters.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
Contents of Core.xaml:
<ResourceDictionary ...>
<viewModel:ViewModelLocator x:Key="Locator" />
</ResourceDictionary>
Now I supposed the resources in Core.xaml are initialized during the InitializeComponent method call in App.xaml.cs, but when I tried to use the ServiceLocator class (which is set in the constructor of ViewModelLocator in MvvmLight) - like this - ServiceLocator.Current.GetInstance<INavigationService>().Navigate<MainViewModel>(); - I get an exception saying:
An exception of type 'System.InvalidOperationException' occurred in
Microsoft.Practices.ServiceLocation.dll but was not handled in user code
Additional information: ServiceLocationProvider must be set.
Indeed, if I put an breakpoint in the constructor of ViewModelLocator, it is not called before the Window is activated. More interestingly still - if I manually reference the Locator resource key (for example putting Debug.WriteLine(Resources["Locator"]); above the call of ServiceLocator), everything works fine. The same goes if I move the ViewModelLocator resource directly to App.xaml - then it is instantiated during IntializeComponent.
Is there a lazy instantiation of merged resource dictionaries in UWP apps? Or why does it behave this way?
A ResourceDictionary in UWP doesn't have any code behind (no InitializeComponent). Therefore, any class references defined in a ResourceDictionary won't be initialized directly.
Neither does the App.InitializeComponent do this for you. Resource dictionaries in UWP just don't provide this functionallity - don't ask me why.
You can easily try this by trying to initialize a DataTemplate in a ResourceDictionary.
This should - sadly - neither work.
However, using the Resources["Locator"] access in code behind triggers the constructor of the class and you're fine.
This ain't be a solution, but a explanation of your problem.
I hope it helps you.

Use an External ResourceDictionary in a WindowsPhone 7/8 app

I have separated libraries for my applications and I want to put ResourceDictionary to keep my default styles in one place.
In my project mylib that is build to mylib.dll i have Styles/General.xaml:
<ResourceDictionary
x:Class="gjdapi.Style.General"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:System="clr-namespace:System;assembly=mscorlib">
I'm referencing it in my App.xaml:
<Application.Resources>
<ResourceDictionary x:Key="General">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/mylib;component/Styles/General.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
Build for Styles/General.xaml is set to Page.
I found some tips here:
Use an External ResourceDictionary in a WindowsPhone 7 app
xClassNotDerivedFromElement error when adding Code Behind to Resource Dictionary in silverlight
Error using ResourceDictionary in Silverlight
but nothing seems to work i always hit this exception:
Message "Parser internal error: Object writer 'xClassNotDerivedFromElement'. [Line: 15 Position: 32]" string
Please tell me what am I missing?
As lisp suggested ResourceDictionary can't have code behind so line x:Class="gjdapi.Style.General" should be removed

VS2010 designer not working when the ResourceDictionary is in a subfolder

I have a project which contains the entry point of my application and a ResourceDictionary. In a first time, these files were located at the root of the project. At this time, I could see all the components (button for exemple) modified by the style in the designer of xaml files in other projects.
Now, I have subfolders like this : src/launcher which contains my entry point and src/styles which contains my ResourceDictionary. But now, the components are not styled in the designer of VS2010. The program compiles and works well, but the designer doesn't work. I get the "Cannot find the resource ..." error constantly.
The code of my main xaml file is :
<Application x:Class="MANAGER.Program"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Startup="Application_Startup">
<Application.Resources>
<ResourceDictionary Source="../Styles/Style.xaml"></ResourceDictionary>
</Application.Resources>
</Application>
Why the designer doesn't work ?
Your code should look this way in order to use subdirectories out of your application root directory:
<Application x:Class="MANAGER.Program"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Startup="Application_Startup">
<Application.Resources>
<ResourceDictionary Source="pack://siteoforigin:,,,../Styles/Style.xaml"></ResourceDictionary>
</Application.Resources>
</Application>
It might have something to do with the format of the "Source" attribute.
The format needs to be a Pack URI like "pack://siteoforigin:,,,/SiteOfOriginFile.xaml"
Have a look at these documentations in MSDN:
ResourceDictionary.Source Property
Packet URIs in WPF

Xaml: C# How to keep style consistent

I'm working on a semi-large windows application using wpf and C# in VS 2010. While working on the xaml, I added a tag so that all buttons and datagrids are styled in the same way. I've copied and pasted this block into several of my .xaml files and that works fine. Of course the problem I'm running into now is that I've added to and changed the style several times.
What is the best way to keep style consistent between my different Windows? Is it subclassing, using Resources.resx, or another way enirely?
If you define the style in the Application level ResourceDictionary (App.xaml), then it will automatically be inherited by your other XAML Windows/Controls.
yeah, if you were to create a new file called Resources.xaml and then add this to your Application.xaml file:
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Resources.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
then you should be able to reference the styles in the Resources.xaml from all the windows in your application.

Categories