FontFamily does not exist - xaml

Want to set global FontFamily and FontSize in a ResourceDictionary, but it's not an option. Why?

That works for me:
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:App59">
<FontFamily
x:Key="MyFamily">Consolas</FontFamily>
<x:Double
x:Key="MyFontSize">48</x:Double>
</ResourceDictionary>
Page
<Page
x:Class="App59.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:App59"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Page.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary
Source="SomeResourceDictionary.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Page.Resources>
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<TextBlock
Text="Hello"
FontSize="{StaticResource MyFontSize}"
FontFamily="{StaticResource MyFamily}"></TextBlock>
</Grid>
</Page>

Related

Use Dictionary from another folder in XAML UWP

this is the content of my dictionary [Dictionaries/myDictionary.xaml]:
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:myApp/Dictionaries"
xmlns:media="using:Windows.UI.Xaml.Media">
<ResourceDictionary x:Key="Default">
<AcrylicBrush x:Key="myAcrylicBrush"
BackgroundSource="HostBackdrop"
TintColor="#202020"
TintOpacity="0.8"
FallbackColor="#202020"/>
</ResourceDictionary>
</ResourceDictionary>
And here is where I need to use it [Pages/myPage]:
<Page
x:Class="myApp.Pages.myPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:myApp.Pages"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:controls="using:Microsoft.Toolkit.Uwp.UI.Controls"
xmlns:animations="using:Microsoft.Toolkit.Uwp.UI.Animations"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Page.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<!-- Here it gives me error -->
<ResourceDictionary Source="pack://application:,,,/ReferencedAssembly;component/Dictionaries/myDictionary.xaml"/>
</ResourceDictionary.MergedDictionaries>
<Style x:Key="myStyle" TargetType="Grid">
<Setter Property="Background" Value="{StaticResource myAcrylicBrush}"/>
</Style>
</ResourceDictionary>
</Page.Resources>
<Grid x:Name="gridPrincipale" Style="{StaticResource myStyle}">
</Grid>
</Page>
I've tried
Source="pack://application:,,,/ReferencedAssembly;component/Dictionaries/myDictionary.xaml"
but it doesn't work…
Both folders "Dictionaries" and "Pages" are in the Project's folder.
For UWP you'll want to use the ms-appx location for the Souce.
Example:
<ResourceDictionary Source="ms-appx:///Company.Themes/Dictionaries/myDictionary.xaml" />
Where Company.Themes is the project name, and Dictionaries/myDictionary.xaml is the location of the resource file from the root of the project

How can I define a theme in a UWP Library?

I'm creating a UWP library that contains custom controls and I want to define a dark and light theme for my controls. I understand that we can add a theme resource dictionary to the App.xaml. We can specify a dark/light theme there and set the requested theme property. But since I am making a library, I don't have an App.xaml in my project. Is it possbile for me to define a theme within the library project? How?
You can create a resource dictionary file in Microsoft Visual Studio by using the Add > New Item… > Resource Dictionary option from the Project menu. Then we can define the ThemeDictionaries in the ResourceDictionary file.
For example:
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:ClassLibrary1">
<ResourceDictionary.ThemeDictionaries>
<ResourceDictionary x:Key="Light">
<SolidColorBrush x:Key="CustomColor" Color="Orange" />
</ResourceDictionary>
<ResourceDictionary x:Key="Dark">
<SolidColorBrush x:Key="CustomColor" Color="Blue" />
</ResourceDictionary>
<ResourceDictionary x:Key="HighContrast">
<SolidColorBrush x:Key="CustomColor" Color="Green" />
</ResourceDictionary>
</ResourceDictionary.ThemeDictionaries>
</ResourceDictionary>
To use that dictionary, we can merge it with control’s dictionary:
<UserControl
x:Class="ClassLibrary1.MyUserControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:ClassLibrary1"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="400">
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Dictionary1.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
<Grid>
<Rectangle Fill="{ThemeResource CustomColor}" Width="500" Height="500"></Rectangle>
</Grid>
</UserControl>
If you want to specify a dark/light theme, you can set RequestedTheme in the Control.

x:Bind in resource dictionary doesn't work

I'm struggling to get a grip of the compiled databinding concept. I have one view (MainPage) that contains a ListBox and one data template (ItemTemplate) used for that ListBox. The MainPage has a MainPageViewModel that contains an ObservableCollection of ItemViewModels. The ItemViewModel contains only one property Name.
MainPage:
<Page x:Class="TestApp.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:TestApp">
<Page.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="ItemDictionary.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Page.Resources>
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<ListBox ItemsSource="{x:Bind ViewModel.Items}"
ItemTemplate="{StaticResource ItemTemplate}" />
</Grid>
</Page>
Resource dictionary containing datatemplate:
<ResourceDictionary
x:Class="TestApp.ItemDictionary"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:TestApp">
<DataTemplate x:Key="ItemTemplate" x:DataType="local:ItemViewModel">
<TextBlock Text="{x:Bind Name}" />
</DataTemplate>
</ResourceDictionary>
This code compiles but when I run it the binding to the Name property fails, although the items get generated. If I use a classic binding everything works fine and if I place the data template directly in the resources for the MainPage it also works. What am I missing?
Correct:
<Page.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<local:ItemDictionary />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Page.Resources>
Incorrect:
<Page.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="ItemDictionary.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Page.Resources>

ListView DataTemplate in separate folder

I'm trying to learn programming apps for Universal Windows Platform. I'm currently working with ListView and I define its layout in <DataTemplate>, but the code is a one mess. Is there a way to define <DataTemplate> in a separate folder? I searched the net but I wasn't able to find a solution. Could you please help me with that? Thanks.
I would always recommend creating a ResourceDictionary for this kind of thing. Here's an example setup:
Create a folder Resources > Add > New item > Resource Dictionary "Templates.xaml"
In your App.xaml add
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Resources/Templates.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
In Templates.xaml you can add any template you want, like so:
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:thestory.Resources">
<DataTemplate x:Key="ListItemTemplate">
</DataTemplate>
You can now reference this template wherever you need it using {StaticResource ListItemTemplate}
Good Luck!
PS: I would actually also recommend doing the same for styles and other application wide resources like font sizes, brushes, backgrounds etc.
In datatemplate.xaml define datatemplate:
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<DataTemplate>
</DataTemplate>
</ResourceDictionary>
In UserControl refer to datatemplate:
<UserControl
x:Class="<assemblyName>.Themes.MyUserControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:PerpetuumSoft.DataManager.UniApp.UI.Themes"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="400">
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="ms-appx:///<AssemblyName>/Themes/DataTemplate.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
<Grid>
</Grid>
</UserControl>

How to bind by element name when control is inside a UserControl?

I am trying to bind the Fill property of a Rectangle to a property in the page's DataContext by using the element name, but because the Rectangle is in a UserControl the page is not found so binding does not occur.
Simplified example:
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:Converters_Theme="using:ProjectName.Common.Converters"
xmlns:CustomControls="using:ProjectName.CustomControls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:ProjectName.Views"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ViewModel="using:ProjectName.ViewModels"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="ProjectName.Views.TestPage"
x:Name="pageName"
mc:Ignorable="d">
<Page.Resources>
<Converters_Theme:ThemeColorToSolidColorBrushConverter x:Key="ThemeColorToSolidColorBrushConverter"/>
<DataTemplate x:Key="ItemDataTemplate">
<StackPanel Orientation="Vertical">
<!-- ... -->
<Rectangle Fill="{Binding DataContext.Theme.Color, Converter={StaticResource ThemeColorToSolidColorBrushConverter}, ElementName=pageName}" MinHeight="40" MinWidth="40" />
<!-- ... -->
</StackPanel>
</DataTemplate>
</Page.Resources>
<Page.DataContext>
<ViewModel:PageViewModel />
</Page.DataContext>
<Grid>
<CustomControls:Tab>
<CustomControls:Tab.LeftContent>
<ItemsControl ItemsSource="{Binding Items}" ItemTemplate="{StaticResource ItemDataTemplate}" />
</CustomControls:Tab.LeftContent>
<CustomControls:Tab.RightContent>
<!-- ... -->
</CustomControls:Tab.RightContent>
</CustomControls:Tab>
</Grid>
</Page>
Simple way to accomplish it is to make your ViewModel a StaticResource, e.g. in App.xaml (may work in your Page.xaml):
<App.Resources>
<ViewModel:PageViewModel x:Key="MyPageViewModel" />
</App.Resources>
And then reference to it in your Page.xaml:
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:Converters_Theme="using:ProjectName.Common.Converters"
xmlns:CustomControls="using:ProjectName.CustomControls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:ProjectName.Views"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ViewModel="using:ProjectName.ViewModels"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="ProjectName.Views.TestPage"
x:Name="pageName"
DataContext="{StaticResource MyPageViewModel}"
mc:Ignorable="d">
<Page.Resources>
<Converters_Theme:ThemeColorToSolidColorBrushConverter x:Key="ThemeColorToSolidColorBrushConverter"/>
<DataTemplate x:Key="ItemDataTemplate">
<StackPanel Orientation="Vertical">
<!-- ... -->
<Rectangle Fill="{Binding Theme.Color, Source={StaticResource MyPageViewModel}, Converter={StaticResource ThemeColorToSolidColorBrushConverter}}" MinHeight="40" MinWidth="40" />
<!-- ... -->
</StackPanel>
</DataTemplate>
</Page.Resources>
<Grid>
<CustomControls:Tab>
<CustomControls:Tab.LeftContent>
<ItemsControl ItemsSource="{Binding Items}" ItemTemplate="{StaticResource ItemDataTemplate}" />
</CustomControls:Tab.LeftContent>
<CustomControls:Tab.RightContent>
<!-- ... -->
</CustomControls:Tab.RightContent>
</CustomControls:Tab>
</Grid>
</Page>
To do it in much more cleaner way, I advise you to use ViewModelLocator as a static resource in app, which will properties to all ViewModels and make it StaticResource in App.xaml. It is much more cleaner way to instantiate one class in App.xaml than every ViewModel you have.