Embedded fonts works for designer but not for application - wpf

I am building a wpf application and I wanted to use Open Sans Regular font in my application.
I referred this link for embedding font. I added OpenSans Regular.ttf file to resources under project properties.
Then I referred them in my application as mentioned below:
<Window x:Class="FontEmbeddingDemo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525" FontFamily="Resources/#Open Sans">
<Window.Resources>
</Window.Resources>
<Grid>
<TextBlock Height="100" Text="This is test text." FontSize="14" FontFamily="Resources/#Open Sans"/>
</Grid>
</Window>
In designer of Visual Studio I can see font changed to open sans but when I run the application it is taking system default font (Arial in my system).
Do let me know if you need any other information.

From MSDN Page:
When you add fonts as resources to your application, make sure you are
setting the <Resource> element, and not the element
in your application's project file. The <EmbeddedResource> element for
the build action is not supported.
So, I guess, you will have to add this font file to your project as you would add any other file and set its BuildAction to Resource instead of adding the font to the Resources under Project Properties, which will make it as an EmbeddedResource.
EDIT
Read this excellent article on how to use custom fonts in a WPF application.
You could also, get this working by way #Sheridan mentioned - which is setting BuildAction to Content. However, the problem with this approach is you will have loose separate file hanging around along with your binary. Users can potentially change this file, which may cause problems with your app. It is best to use Resource as BuildAction as the font gets bundled into the assembly.

In my opinion, I believe that the accepted answer to this question may either be incorrect, or misleading. I am using Font files in exactly the same way and I have absolutely no need to set their BuildAction to Resource. My Font files have a BuldAction set to Content and that works just fine. I'm guessing that the accepted answer would only help users that have set their Font file to EmbeddedResource.
The comment that #sthotakura quoted from the linked MSDN page is merely talking about manually editing the project file, which the question author is not doing. Note that there is no mention of BuildAction property in the linked page apart from mentioning that the EmbeddedResource value is invalid in this case.
Please try this instead or as well:
Set the BuildAction of the Font file(s) to Content.
Reference the Font file like this (with the all important starting slash):
FontFamily="/Resources/#Open Sans"
I just tried removing the starting slash in my project and the Font defaulted to another Font, so I'm pretty sure that this will work... all the same, please let me know. I'm more than happy to remove this answer if I am mistaken.

Related

XAML Intellisense doesn't work for Referenced Assembly Resources

I'm trying to create a project dll file that holds core styles, resources, controls, etc. This will then be referenced into various other projects to use as a graphic base to unify the appearance.
Anyway, I have the graphics project set up and I can use it in other projects and it all seems to display correctly. However, XAML intellisense for my static resources doesn't seem to be working.
Here is my resource dictionary reference:
<ResourceDictionary Source="pack://application:,,,/BIT.GraphicElements;component/BITCoreStyles.xaml" />
As you can see I'm using pack notation to reference it inside it's assembly. I can style elements like I would expect (StButtonAction is in the above dictionary):
Style="{StaticResource StButtonAction}"
However, I have to type it in manually. Intellisense doesn't give it as an option but if I type it manually is applies it successfully. It also works if I add the project to the solution and reference it there, however this is intended to be used by those that don't necessarily have access to the graphics project so that's not a good solution in the long run...
What am I missing? Is there a way to make Intellisense work for these?
Maybe this'll help future searchers even if it doesn't fix your specific problem.
When you have a solution involves external dll then you can occasionally find resources just don't get loaded at design time. At all. Even though you merge in app.xaml the things don't turn up until you run.
It looks like some sort of subtle bug to me.
The way I work round this is to use functionality originally intended for Blend. We are now using the blend designer in visual studio.
In solution explorer, add a resource dictionary to Properties. Yes. Properties. Create it first in your project and drag it up there. This must be called DesignTimeResources. This can then merge any resource dictionaries you will want to use just for design time or when you have an issue makes you think resource dictionaries aren't getting loaded for design time.
Mine is in army editor but uses resources from a referenced dll, UILIb. It looks like:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:ArmyEditor">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/UILib;component/Resources/UILibResources.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
This is a resource dictionary in a bit of an odd place but nothing particularly weird so far.
Next is the bit that many developers will never have done - editing your csproj.
Right click your project and choose unload.
Right click it again and edit it.
In there you will have entries for all the stuff makes up your project. And of course breaking this would be bad so maybe you want to back up first.
If you don't use blend then I think the important thing here is to add a node which says ContainsDesignTimeResources True, but here's mine:
<Page Include="Properties\DesignTimeResources.xaml" Condition="'$(DesignTime)'=='true' OR ('$(SolutionPath)'!='' AND Exists('$(SolutionPath)') AND '$(BuildingInsideVisualStudio)'!='true' AND '$(BuildingInsideExpressionBlend)'!='true')">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
<ContainsDesignTimeResources>true</ContainsDesignTimeResources>
</Page>
Save your edits.
Reload your project.
When the designer is open, you should find resources from it are loaded. Maybe this will help intellisense find them.
I mentioned this earlier but.. In my experience, such intellisense on resources is often unreliable.
This definitely solved a similar issue I have had in this solution. It is also useful when you want to temporarily overlay resource dictionaries for localisation/branding testing.

Understanding Templates

I'm struggling with Templates in WPF
I understand the concept in that I can have a control, and 'override' the ContentTemplate (or similar). I use it often with the TabControl
However, I don't understand it in terms of what the initial control looked like. And if we are limited on the names. EG, could we build a control and overwrite the NonsenseNameTemplate?
If I were to build my own UserControl and provide the ability for people to override things like my NonsenseNameTemplate, what would this code look like?
My guess, with pseudo code would be
<UserControl>
<NonsenseNameTempalte>
//some resources
//some other controls
</NonsenseNameTempalte>
</UserControl>
In the above example, I can fully understand how I could create a new control and overwrite the NonsenseNameTemplate but I can't see any code examples of the UserControl and it's usage.
Template is nothing more than a (dependency) property. By writing
<Button>
<Button.Template>
<ControlTemplate>
...
</ControlTemplate>
</Button.Template>
</Button>y
you are doing nothing more than creating a new instance of ControlTemplate class and assigning it to Button.Template property of that specific button. Each control has it's own ControlTemplate saved somewhere in it's assembly. It is generally not so simple to actually get those default templates, but Blend can help with it.
Of course, you can create your won NonsenseNameTemplate property, but actually using it would require some deep knowledge of WPF composition, layouting and rendering. Which is usually not required for normal usage of WPF. And I agree that there is not a much online resources about doing something like this, for exactly this reason.
I too had an early on learning of Templates. I posted a step-by-step answer to another question via a customized button control. The nice thing about that sample, you can build and play with styles and templates in a small project and see visual impact without requiring full project rebuild
To start with, as you have mentioned that you do not have Blend. You can have Blend and install it with Visual Studio 2013 Community.
You can download this here if you do not have it already.
http://www.visualstudio.com/products/visual-studio-community-vs
A part of the installation process, it allows you to select and install Blend. Also, the newer editions of visual studio give you some of the power of blend. In your design view you can right click on a control and create or copy a template.
On to the question.
As Euphoric has mentioned. Custom control authoring does require a little more in-depth knowledge of WPF, or any of the XAML frameworks. However, there are Visual Studio templates that can help you in the right direction.
As for the template naming, you have three types of templates you will come across in XAML. ControlTemplate (which for your purposes is the one we are interested in), ItemsPanelTemplate and DataTemplate. Again, as Euphoric has said, there are few circumstances where deriving a custom version of any of these three templates would bring anything to the table.
If you were to create a test WPF application, once you have created the basic project and solution. Go a head and add in another project, and from the templates VS provides, File -> Project -> New -> Windows Desktop. In the project template list, find 'WPF Custom Control Library'. Once created, reference this project in your main WPF project.
This custom control library project will give you a skeleton setup for what you are looking for.
If you look in this project here are some things for you to note.
Firsty, you will find a folder called Themes and in there a file named Generic.xaml. In there you will see a style that has a setter setting the Template property. You will also see that both the Style and set ControlTemplate have a set TargetType that should be local:CustomControl1.
This is important as this is showing you how to create a custom controls default template. Now, to apply this template look in CustomControl1.cs and consider the following code.
DefaultStyleKeyProperty.OverrideMetadata(typeof(CustomControl1), new FrameworkPropertyMetadata(typeof(CustomControl1)));
For this control named CustomControl1, that template we looked at in the xaml will be automatically set as that controls default template where ever that control is used.
This project is a good starting point. But now you may want to override this ControlTemplate inside your main project. This is simple. I have code that looks something like this inside my main WPF project.
At the top of the MainWindow.xaml
<Window x:Class="CustomControlTesting.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:CustomControl="clr-namespace:CustomControlTesting.CustomControlLibrary;assembly=CustomControlTesting.CustomControlLibrary"
Title="MainWindow" Height="350" Width="525">
And in the body,
<CustomControl:CustomControl1>
<CustomControl:CustomControl1.Template>
<ControlTemplate TargetType="{x:Type CustomControl:CustomControl1}">
<Grid>
<!-- Define my look to override the template -->
</Grid>
</ControlTemplate>
</CustomControl:CustomControl1.Template>
</CustomControl:CustomControl1>
This is a brief overview and certainly misses out a lot. But I hope this is of help to you and can get you started.

Set default xaml window background image in dll

I am currently developing a default WPF control Kit.
But I am stuck with using the correct kind of uri in xaml.
What I have is an image wich should be used as the background for the non-client area of my window.
To make the default controls available very easy I want to put everything in a dll.
Other apps can quickly reference that dll and get access to the style.
The problem is, that my image is not showing up when using the dll style in an app.
My image (/Resources/WindowBackground.jpg) is set to Resource and I am using the following xaml:
<Image Grid.ColumnSpan="99" Grid.RowSpan="99">
<Image.OpacityMask>
<ImageBrush ImageSource="pack://application:,,,/Resources/WindowBackground.jpg"/>
</Image.OpacityMask>
</Image>
I also tried:
<Image Grid.ColumnSpan="99" Grid.RowSpan="99" Source="/Resources/WindowBackground.jpg"/>
Both write the following into the output (Couple times):
..."System.IO.IOException" in PresentationFramework.dll...
I also tried lots of other uris wich sometimes lead to XamlParseExeptions and other not so nice stuff.
Thank you for any hints :D
You can find your answer in the Pack URIs in WPF page on MSDN. For your particular situation, you can use the following syntax to reference your resource image file:
pack://application:,,,/ReferencedAssembly;component/Resources/WindowBackground.‌​jpg
From the linked page:
The following example shows the pack URI for a XAML resource file that is located in a subfolder of the referenced assembly's project folder.
pack://application:,,,/ReferencedAssembly;component/Subfolder/ResourceFile.xaml
Note: The type of resource file here is irrelevant.

How can I discover WPF resources defined in another assembly?

I'm writing some extension modules for a WPF Composite application supplied by another vendor. The application is themed, and gives users the option to select from a number of themes which will change the appearance of the entire applications, including any custom modules that register themselves with the theme manager appropriately.
I really want my custom extensions to look like an integrated component, so I'm trying to use only styles defined as resources within the main application. As I'm still learning the nuances of XAML, I'm styling more by trial and error.
I'm wondering if there's a way of 'discovering' what styles are available in a different assembly. Here is an example of what I'm currently doing.
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<common:DesignTimeResourceDictionary Source="/Vendor.Desktop.WPFCommon;component/themes/generic.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
<Border
Background="{DynamicResource LightGradientBackgroundBrush}"
Margin="0"
>
The LightGradientBackgroundBrush is defined in the vendors assemblies. By including the above ResourceDictionary, the style is present during design time, and the brush isn't underlined in the XAML editor.
Can I find what other styles are defined? I'm only aware of that style because it was mentioned in passing in a sample provided by the vendor.
Edit:
I'm aware of a BAML add-in for reflector, but it doesn't work with reflector 7 unless it has been recompiled/patched. Someone has already done that here though.
I was hoping there was a better solution though. Intellisense for styles would be great.
There used to be a Reflector add-in for viewing BAML resources that worked well for that. But I haven't used Reflector in a while since Redgate crashed the party. It may not work with the current version.
You know where your resource dictionary is so you should be able to load it up in code and enumerate over the available resources. This will at least give you an idea of what's available.
See this link: http://blogs.claritycon.com/leeroth/2009/05/20/load-xaml-resource-dictionaries-at-runtime/
Enumerate over the Keys property and use the item property to access the resources. You can get as detailed as you want, but at the very least you should be able to spit out the resource names.

Can't use WPF designer because can't find custom base window type in XAML, but code behind is fine

I am using a base Window class in a WPF project. In the code behind C# file the assembly to the base type is referenced and fine. In the XAML is looks like this:
<MyNamespace:WindowBase x:Class="MyNamespace.Applications.UserInterface.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:MyNamespace="clr-namespace:MyNamespace.Somewhere;assembly=MyNamespace.Common"
Title="MainWindow" Height="350" Width="525">
<Grid>
</Grid>
The solution compiles fine and I can run it. I just can't use the designer in VS 2010. It throws the following exception: The type'MyNameSpace:WindowBase' was not found. Verify that you are not missing an assembly reference and that all referenced assemblies have been built.
Well. they have been. I can't understand what this issue is. This particular base class is used in other projects just fine. I grabbed it for a new project and I can't use the designer. Very frustrating.
Found this problem just recently (this answer upgraded from a comment).
If you copy the dll from a network path, you must right click on the file in Windows Explorer, select Properties, then 'unblock'; there is a hidden NTFS stream associated with the file, and many files when you download from the 'net or copy from a network path, for security reasons.
Only the designer complains, yet the project builds and runs fine: weird isn't it?!
Whenever the designer is acting up against me - the first thing I do is clear the obj-folders in the project and rebuild. Sometimes they seem to go out of sync for some reason (usually when I'm drag-dropping a lot of files and renaming visual items).
I dont't know if its the same issue but in VS2008 I tried to make abstract UserControls but had to change this because the designer didnt't support any abstract base classes (however the solution was compilable and also worked as excpected).
Fixed. The library that contained my base class resided on a drive on the network that I did not have permissions to. That seemed to have no affect on VS 2008 as it worked, but VS 2010 apparently took exception to that when the designer tried to load it. Weird.

Resources