Setting style on/in UserControl without having to define MergeDictionary? - wpf

I'm looking to set a style on some UserControls that's kept in a resource dictionary at the base of my project tree. The only way I've found to do so is below by defining MergeDictionary in the resources to link in the xaml file with styles. I'd prefer to not have to put this same code on every single control that needs this style though. Is there a better way to do this?
<UserControl
x:Class="TestApp.Screens.Sub.Details"
...
Style="{DynamicResource BottomContentUserControl}">
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="../../GeneralStyles.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
</UserControl>

You can add the styles to the ApplicationResourceDictionary or you could add them to your App.xaml file so that they will be applied throughout your application.

Related

How can I access a dynamic resource from a different assembly inside a ViewBase

I am working with a Xaml file that is a custom view derived from a ViewBase, and I would like to access a DynamicResource that is in a different assembly. I have seen that it is possible to use something like:
<Application.Resources>
<ResourceDictionary
Source="/mylib;Resources/MyStyleDictionary.xaml" />
</Application.Resources>
However I'm dealing with a xaml file that looks something like:
<myLib:ViewBase>
<Grid>
<Button>
Style="{DynamicResource MyButtonStyle}" // I want this style to come from a different assembly
</Button>
</Grid>
</myLib:ViewBase>
How can I do this?
It's important to understand the difference between Dynamic and Static resources. What's the difference between StaticResource and DynamicResource in WPF?
But to answer the question:
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/SomeOtherAssembly;Resources/SomeOtherDictionaryWithMyButtonStyleKey.xaml" />
<ResourceDictionary Source="/mylib;Resources/MyStyleDictionary.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
The resource is being referenced dynamically, so merging SomeOtherDictionaryWithMyButtonStyleKey.xaml before merging in MyStyleDictionary.xaml should work.

DataTemplate in a separate ResourceDictionary

I know there a lot of topics related to this question but I could not find a solution that fits perfectly for my problem ... maybe there is none?
At the moment I have a UserControl which holds a navigation which allows the user to switch between different screens. These screens are defined in the Resources part of my UserControl as DataTemplate.
Something like that:
<DataTemplate TargetType={x:Type vm:ViewModel1}>
...
</DataTemplate>
<DataTemplate TargetType={x:Type vm:ViewModel2}>
...
</DataTemplate>
<DataTemplate TargetType={x:Type vm:ViewModel3}>
...
</DataTemplate>
Ok and what I wanna do is to place these DataTemplates in a separate XAML file and link this file to the UserControl's resources part. Do I really have to make this new XAML Resource Dictionary globally available in my application (adding it to the App.xaml resources) or is there another/better way?
No you do not have to make it global. Simply declare resource dictionary in your user control resources section just the same way as you did in app.xaml.
<Control.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Dictionary1.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Control.Resources>
You can point to file using relative file path "..\Folder\Folder\Dictionary.xaml" if you need to.

Referencing Resource Dictionaries in a separate project

I've recently split my silverlight application into several smaller projects.
I've moved all of the resource dictionaries containing my styles into a separate project ("Application.Themes") I then reference these from my App.xaml file within my main project.
This works fine for the main project however all other projects that reference styles within these resource dictionaries throw "Object Reference not set to an instance of an object" exceptions within the designer, although they do compile and run without any problems and with the correct styles.
I've added an App.xaml file to each of the individual projects which references the same dictionaries as my main App.xaml file, this has made no difference.
Is there a correct way to reference resource dictionaries from another project which allows the designer to be used?
EDIT:
Here is some more information and some code snippets to demonstrate the issue I'm having
I have a styles project called "Themes" within this project I have several dictionaries that define all of the styles for the project.
Within my main App.xaml I have the following
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/Themes;component/Styles/CoreStyles.xaml"/>
<ResourceDictionary Source="/Themes;component/Styles/Styles.xaml" />
</ResourceDictionary.MergedDictionaries>
If I reference styles within the main project they work correctly. however they don't for any other projects even if those projects reference the Themes project.
I've attempted to put the following at the start of each UserControl in order to resolve the styles at design time, however it still cannot resolve styles that are within the project.
<UserControl>
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/Themes;component/Styles/CoreStyles.xaml"/>
<ResourceDictionary Source="/Themes;component/Styles/Styles.xaml" />
</ResourceDictionary.MergedDictionaries>
<!-- Additional Control Specific resources -->
</ResourceDictionary>
</UserControl.Resources>
<!-- The following resources are defined in Styles.XAML and don't resolve at design time and throw errors -->
<TextBlock Text="Header Test"
FontFamily="{StaticResource HeaderFontFamily}"
Foreground="{StaticResource StrongBrush}">
</UserControl>
My styles.xaml looks similar to this.
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:behaviors="clr-namespace:Minerva.Presentation.Behavior;assembly=Minerva.Presentation"
xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation">
<SolidColorBrush x:Key="StrongBrush" Color="{Binding Source={StaticResource MetroColors}, Path=Palette.StrongColor}" />
<FontFamily x:Key="HeaderFontFamily">Segoe UI Light, Lucida Sans Unicode, Verdana</FontFamily>
</ResourceDictionary>
Create an assembly for the styles/themes project so that this can be referenced by other projects.
In order to merge these styles into application either at app.xaml/page.xaml using MergedDictionaries
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/Assembly;component/Stylesorthemes.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
Hope this is useful.
I created an assembly test which contains the resource dictionary Theme.xaml
Theme.xaml code
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Thickness x:Key="GeneralThickness">10</Thickness>
</ResourceDictionary>
I created seperate silverlight project testreturns
case1.In App.xaml
<Application xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="testreturns.App"
>
<Application.Resources>
<ResourceDictionary >
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/test;component/Theme.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
case2.Usercontrol level
<UserControl.Resources>
<ResourceDictionary >
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/test;component/Theme.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
And using it to set borderthickness of button
<Button Height="50" Width="150" BorderThickness="{StaticResource GeneralThickness}"/>
In both cases it is working for me.
Is this what you intend for?
Did you set the theme.xaml file properties BuildAction to Resource while creating assembly?

Adding resources into Silverlight application

I am trying to add resource dictionary into my silverlight-4 aplication (suggested in "Applying a View to a ViewModel" chapter of the http://msdn.microsoft.com/en-us/magazine/dd419663.aspx article).
The 1st problem: I don't see any resource in my MainPage. Am I correctly understand that I need to add resource dictionary manually into Silverlight app?
The 2nd: When I did that, in the Dictionary1.xaml file
<ResourceDictionary
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">
<DataTemplate DataType="{x:Type vm:MyViewModel}">
<vw:MyView />
</DataTemplate>
</ResourceDictionary>
I am getting an error: Can't resolve a symbol 'DataType'...
Is there any idea hot to do that?
ad 1: MainPage has a ResourceDictionary. You add elements to it in xaml like this:
<MainPage>
<MainPage.ResourceDictionary>
<DataTemplate>
<vw:MyView />
</DataTemplate>
</MainPage.ResourceDictionary>
...
You can add a ResourceDictionary to the MainPage.ResourceDictionary by using the Source and MergedDictionaries properties of ResourceDictionary:
<MainPage>
<MainPage.ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Dictionary1.xaml"/>
</ResourceDictionary.MergedDictionaries>
</MainPage.ResourceDictionary>
...
ad 2: DataTemplate does not have a Property DataType in the Silverlight framework. :-(
You also need to add an x:Key into the DataTemplate if it's going to be in the ResourceDictionary.

Why can't I find DataTemplates in merged resource dictionaries?

In my MainWindow.xaml, I have the following reference to a ResourceDictionary:
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="MainSkin.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
In MainSkin.xaml, I define a datatemplate:
<DataTemplate x:Key="TagTemplate">
...
</DataTemplate>
Deeper within my application, I attempt to use this data template:
<ContentControl DataContext="{Binding Tag}" ContentTemplate="{StaticResource TagTemplate}"/>
The code compiles successfully, but when I attempt to load a Page or UserControl that contains this StaticResource, I get an exception saying that the TagTemplate can't be found.
What am I doing wrong?
In order to access the contents of a resource defined in a XAML file, you need to "include" that XAML file in each page and control that uses it. So every XAML files will need to have the MergedDictionaries entry that you have in MainWindow.xaml.
Alternatively you can add those merge dictionaries to App.xaml and those resources are included implicitly:
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="MainSkin.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
Are you using that StaticResource in the same Window where it is declared? Otherwise I think that you cannot have access to that.

Resources