I have created a global font resource in App.xaml like this:
<Application.Resources>
<ResourceDictionary>
<FontFamily x:Key="GlobalFontLight">Arial</FontFamily>
<FontFamily x:Key="GlobalFont">Segoe UI</FontFamily>
<FontFamily x:Key="GlobalFontBold">Caibri</FontFamily>
</ResourceDictionary>
</Application.Resources>
In MainPage I have added a TextBlock:
<TextBlock Text="Some text" FontFamily="{StaticResource GlobalFont}" Foreground="Black"/>
<TextBlock Text="Some text 2" FontFamily="{StaticResource GlobalFontLight}" Foreground="Black"/>
<TextBlock Text="Some text 3" FontFamily="{StaticResource GlobalFontBold}" Foreground="Black"/>
And it is ok, TextBlock use my global font.
Now, I want to change that global font in Application Resources. I have tried next code:
Application.Current.Resources["GlobalFont"] = new FontFamily("Arial");
But nothing happens, TextBlock still use the old font. If I run this code before InitializeComponent(); then it is working as I want, but after that no. Anyone knows what do I do wrong? How to achieve this dynamic change of font?
Because UWP does not support DynamicResource this is quite a problem. The StaticResource and ThemeResource extensions won't save you here, because they are bound only when evaluated and will not update for the already-evaluated properties when the underlying resource changes.
The first option would be to navigate back and navigate to the same page again, so that the controls get reloaded and the resources evaluated anew.
If you want something more dynamic, please check out my answer on this SO question. If you follow that solution, you can create a class implementing INotifyPropertyChanged that will contain a property of type FontFamily, store this instance in a StaticResource and then use binding instead of StaticResource like this:
<TextBlock Text="{Binding Font, Source={StaticResource CustomUISettings}}" />
Related
I trying write app in WPF (C#) and I would like use ttf font for digital clock style.
I get font from internet, in archive i have 4 files. Add it to project into Font folder. Actions for file is Resource and Copy always. Then i add font-resource for my control in xaml:
<Control.Resources>
<FontFamily x:Key="DS-Digital">.\..\Fonts\#DS-Digital</FontFamily>
</Control.Resources>
And use it to TextBlock:
<TextBlock FontFamily="{StaticResource DS-Digital}"
Foreground="GreenYellow"
Text="{Binding GameTime, Converter={StaticResource SecondsCoverter}}"/>
It work. But it font not monospace. Then I downloaded another font. It monospace. In new archive i had only one file. Add it to project and use like previous font:
<Control.Resources>
<FontFamily x:Key="DS-Digital">.\..\Fonts\#DS-Digital</FontFamily>
<FontFamily x:Key="MonoDigital">.\..\Fonts\#Digital-7</FontFamily>
</Control.Resources>
and
<TextBlock FontFamily="{StaticResource MonoDigital}"
Foreground="GreenYellow"
Text="{Binding GameTime, Converter={StaticResource SecondsCoverter}}"/>
But it not applied. What i doing wrong?
Thank you for answer and sorry my english.
I've spent the better of half a day trying to make the ItemTemplate of a ListView with a UserControl configurable through means of a DependencyProperty on said UserControl. I've come across some weird inconsistencies regarding the two different Binding methods available on Windows 10 UAP platform ( Binding and x:Bind).
The UserControl looks like this and is part of a custom calendar component.
<UserControl
x:Class="FlowDesigner.UserControls.CalendarDayView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:FlowDesigner.UserControls"
xmlns:vw="using:FlowDesigner.ViewModels"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:uc="using:FlowDesigner.UserControls"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="400"
x:Name="DateControl">
<UserControl.Resources>
<DataTemplate x:Key="DefaultDataTemplate" x:DataType="vw:Event" >
<uc:EventListTemplate IsToday="{Binding Date, Converter={StaticResource IsTodayConverter}}"
Date="{Binding Date, Mode=OneWay}"
Summary="{Binding Path=Summary, Mode=OneWay}" />
</DataTemplate>
</UserControl.Resources>
<RelativePanel Background="White" BorderBrush="Black" BorderThickness="1" DataContext="{Binding ElementName=DateControl}">
<TextBlock x:Name="DayText" TextAlignment="Center" VerticalAlignment="Center" />
<TextBlock x:Name="MonthText" TextAlignment="Center" VerticalAlignment="Center" RelativePanel.RightOf="DayText" />
<ListView x:Name="EventList" ItemsSource="{x:Bind Events, Mode=OneWay}"
ItemTemplate="{Binding Path=EventItemTemplate, Mode=OneWay, FallbackValue={StaticResource DefaultDataTemplate}, TargetNullValue={StaticResource DefaultDataTemplate}}"
RelativePanel.Below="DayText" RelativePanel.AlignLeftWithPanel="True" RelativePanel.AlignRightWithPanel="True">
</ListView>
</RelativePanel>
</UserControl>
The EventItemTemplate is a DependencyProperty of the UserControl.
public DataTemplate EventItemTemplate
{
get { return (DataTemplate)GetValue(EventItemTemplateProperty); }
set { SetValue(EventItemTemplateProperty, value); }
}
public static readonly DependencyProperty EventItemTemplateProperty =
DependencyProperty.Register("EventItemTemplate", typeof(DataTemplate), typeof(CalendarDayView), new PropertyMetadata(null));
Which is altered on one of the root pages to style the ListView in one way or the other, like so.
<Style TargetType="uc:CalendarDayView">
<Setter Property="EventItemTemplate">
<Setter.Value>
<DataTemplate x:DataType="vw:Event" >
<TextBlock Text="{Binding Summary, Mode=OneWay}" />
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
This is actually a working version, but I had to tinker around with it quite a bit. The first attempts were made by me with both x:Bind and Binding and without the DataContext on the RelativePanel as the UserControl is now. x:Bind would be functional when setting a value to EventItemTemplate in the root page, but it would not be able to use the default DataTemplate specified by the StaticResource when the root page did not specify anything. Binding on the other hand would use the default DataTemplate at all times, even when the the root page had a set an other value to EventItemTemplate.
By setting the DataContext on the RelativePanel to the UserControl Binding started worked like wanted it too. x:Bind still shows the same behavior.
Now I understand that Binding does not by default bind to the UserControl's DataContext, but I'm still not entirely sure why x:Bind doesn't work. Is this intended behavior or is there something wrong with my entire scheme here and is what I came up with just a lucky hack?
From {x:Bind} markup extension:
The {x:Bind} markup extension—new for Windows 10—is an alternative to {Binding}. {x:Bind} lacks some of the features of {Binding}, but it runs in less time and less memory than {Binding} and supports better debugging.
At XAML load time, {x:Bind} is converted into what you can think of as a binding object, and this object gets a value from a property on a data source. The binding object can optionally be configured to observe changes in the value of the data source property and refresh itself based on those changes. It can also optionally be configured to push changes in its own value back to the source property. The binding objects created by {x:Bind} and {Binding} are largely functionally equivalent. But {x:Bind} executes special-purpose code, which it generates at compile-time, and {Binding} uses general-purpose runtime object inspection. Consequently, {x:Bind} bindings (often referred-to as compiled bindings) have great performance, provide compile-time validation of your binding expressions, and support debugging by enabling you to set breakpoints in the code files that are generated as the partial class for your page. These files can be found in your obj folder, with names like (for C#) .g.cs.
I using a separate project for my styles a and i have some line of codes like this in it:
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
>
<Style x:Key="NazaninFont" TargetType="Control">
<Setter Property="FontFamily" Value="pack://application:,,,/Extra/Fonts/#IRNazanin"/>
</Style>
......
</ResourceDictionary>
My another styles (like control effects and...) work well when i use my style key in the element like this:
Style="{ms:MyStyleRef ResourceKey=MyStyleKey}"
But When i use the following code in my Lable element
<Label Style="{ms:MyStyleRef ResourceKey=NazaninFont}" x:Name="LabelRemainingSec" Content="{Binding RemainingSec}"/>
I have:
In Design Time >> The FontFamily is set on IRNazanin on the properties panel but have not correct font view in the designer!
BUT
In Run Time >> The FontFamily is set on Tahoma (Window font)
Also i tested this way:
I added a style base on my font styles in the separate project, in top of my Window, like this:
<Style x:Key="NazaninFont" BasedOn="{ms:MyStyleRef ResourceKey=NazaninFont}" TargetType="Label"/>
Then i use it in my Lable normaly:
<Label Style="{StaticResource NazaninFont}" x:Name="LabelRemainingSec" Content="{Binding RemainingSec}"/>
Result is same as previous way:
In the Design Time in the FontFamily is on IRNazanin and have not correct font view in XAML designer! And in Run Time it is on Tahoma
What do you think about my problem? I think think my styles can not give the font path to the Label control correctly.
This may or may not be what you are after, but I'll take a guess that it is :p
You can define a FontFamily Resource in your resource dictionary, or where ever you want really. Take note of how I have defined it in Window.Resources.
I have included the physical font file in my project inside a folder called 'fonts' (no need for packing), and referenced it using the Font name: value. This is found by double clicking the font file (where it displays a whole heap of demo text and the option to install). You do not use the name of the file itself, you use the Font name: value when referencing. Also, don't forget the # at the start of any font reference! :)
Then, call it like you would any other resource for font family
Both the labels will be a different font. Please note that the font change won't be visible during design time unfortunately, only during runtime.
Working code as a demonstration:
<Window x:Class="Tinker.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="400" Width="500">
<Window.Resources>
<FontFamily x:Key="MyFont">fonts/#Roboto Thin</FontFamily>
</Window.Resources>
<StackPanel VerticalAlignment="Top">
<Label FontSize="36" Content="Helloooooo World!"/>
<Label FontSize="36" FontFamily="{StaticResource MyFont}" Content="Helloooooo World!"/>
</StackPanel>
</Window>
I need to create a button with two lines of text:
The first one is Command Title like "Save"
The second one is a Description of the Command like "The application state will be saved"
So I have written the next xaml:
<Button Margin="0,128,0,0" Padding="10,5" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch">
<StackPanel Margin="0" UseLayoutRounding="False">
<TextBlock FontSize="{StaticResource PhoneFontSizeMediumLarge}" FontFamily="{StaticResource PhoneFontFamilySemiBold}">Save</TextBlock>
<TextBlock Style="{StaticResource PhoneTextSubtleStyle}" Margin="0">The application state will be saved</TextBlock>
</StackPanel>
</Button>
This code working well except a one issue. The Description line becomes invisible when the button is pushed.
I'm sure the root cause is the low contrast color of the description line. But I don't know how to fix it.
Update: I have tried to use the PhoneTextSubtleStyle style but still have the same issue.
You could retemplate the Button (using the Control.Template property) to look different so that when pushed it no longer interferes with the content.
Could you try something like this
System.Windows.Visibility.Visible;
System.Windows.Visibility.Hidden;
or
System.Windows.Visibility.Collapsed
here is a link that will show an example of how to use this inside of a StackPanel
How to: Change the Visibility Property
I store user specified settings using application settings properties and databinding. It has been working fine, until i want user selected to font for combobox. Databinding between user settings and combobox not working. I want to store font family name.
App.XML
<Application.Resources>
<ResourceDictionary>
<properties:Settings x:Key="Settings" />
</ResourceDictionary>
</Application.Resources>
Window.XML
<ComboBox Name="Families" ItemsSource="{x:Static Fonts.SystemFontFamilies}"
<!-- This line -->
SelectedItem="{Binding Source={StaticResource Settings}, Path=Default.Font, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
Margin="57,122,199,118">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}" FontFamily="{Binding}"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
Settings:
font String User Arial
In what way isn't it working? Is an exception thrown, is the project not compiling, or is the setting is not getting saved?
Don't forget that you must expressly save settings once they are modified. For this reason, you might do better to bind to an ICommand that applies and saves the setting, rather than to the setting directly, or add a "save" button that is bound to such a command.
Adding SelectedValuePath="Source" solve this problem.