Reputation: 33784
All my grids could be small and very big depending on window size but text inside is looking really small on big grid sizes.
My current idea (but I don't know how to realize it yet) is to make Binding for all Grid elements to single font and then change the font size by
override void OnRender(DrawingContext dc) {
depending on window size.
The question is: Is this idea sane and is there other methods for it?
Upvotes: 1
Views: 197
Reputation: 1
I know this is an old post but it was one of the first things to come up when I searched for the topic, so here is my solution:
I've done this in a project recently for work with text boxes and scaling their content font size relative to the screen. For this I set up an integer value and had font size bound to it.
In my case, my screen height starts at 800x650 and I wanted my font to be size 12 by default so I set the integer value (_ScaledFontSize) to WindowHeight/(650/12).
Everytime the screen size changes, a function is called to recalculate the font size and a property change event is called. This function is where you can add constraints for minimum and maximum font sizes using something simple like:
//Set a minimum font size
if(_ScaledFontSize < 12)
_ScaledFontSize = 12;
In order to enforce this scaled sized, every control that you want to scaled font size on must be bound to the ScaledFontSize property.
Final Result:
Text at about 1920x1080 (Slightly smaller because not fullscreen)
I was struggling to find something like this for a while and in the end this is what I went with. Luckily the code is pretty simple: MainWindow.xaml.cs:
using System.Windows;
using System.ComponentModel;
namespace FontScaling
{
public partial class MainWindow : Window, INotifyPropertyChanged
{
public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
private int _ScaledFontSize;
public int ScaledFontSize
{
get => _ScaledFontSize;
set => _ScaledFontSize = value;
}
public void PropChange(string name)
{
System.ComponentModel.PropertyChangedEventArgs propertyChangedEvt = new System.ComponentModel.PropertyChangedEventArgs(name);
if (PropertyChanged != null)
{
PropertyChanged.Invoke(this, propertyChangedEvt);
}
}
public MainWindow()
{
InitializeComponent();
_ScaledFontSize = (int)Application.Current.MainWindow.Height / 54;
}
private void Window_SizeChanged(object sender, SizeChangedEventArgs e)
{
_ScaledFontSize = (int)Application.Current.MainWindow.ActualHeight / 54;
PropChange("ScaledFontSize");
}
}
}
MainWindow.xaml:
<Window x:Class="FontScaling.MainWindow"
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:FontScaling"
mc:Ignorable="d"
Title="MainWindow" Height="650" Width="800"
SizeChanged="Window_SizeChanged"
Name="_This">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="10*"/>
<RowDefinition Height="10*"/>
<RowDefinition Height="10*"/>
<RowDefinition Height="200*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="15*"/>
<ColumnDefinition Width="10*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="10*"/>
<ColumnDefinition Width="15*"/>
</Grid.ColumnDefinitions>
<TextBlock
VerticalAlignment="Bottom"
Grid.Row="1"
Grid.Column="1"
Text="Non Scaled TextBlock"/>
<TextBox
Grid.Row="2"
Grid.Column="1"
Text="Non Scaled Text"/>
<TextBlock
VerticalAlignment="Bottom"
Grid.Row="1"
Grid.Column="3"
Text="Scaled TextBlock"
FontSize="{Binding ScaledFontSize, ElementName=_This}"/>
<TextBox
Grid.Row="2"
Grid.Column="3"
Text="Scaled TextBox"
FontSize="{Binding ScaledFontSize, ElementName=_This}"/>
</Grid>
</Window>
Upvotes: 0
Reputation: 125
I like more this solution as suggested by roberther. It is more aesy and clean.
<Viewbox>
<TextBlock Text="Hello World" />
</Viewbox>
Upvotes: 0
Reputation: 18472
If you have not set the font on inner elements explicitly, they inherit the parent font. So you can change the font size on one of the parent elements (for example the Window
itself or the Grid
). This changes the font size on all inner elements that has not specified the font size explicitly.
However if your font should be of different sizes, the best solution in my opinion is binding the font size of elements to the font size of the parent window, and using a value converter to do a scale on the font size:
Define a value converter like this:
using System;
using System.Windows.Data;
namespace WPFTest
{
public class FontSizeConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value == null)
return null;
double windowFontSize = (double)value;
var scale = System.Convert.ToDouble(parameter);
return windowFontSize * scale;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
}
And use it in your xaml:
<Window x:Class="WPFTest.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:test="clr-namespace:WPFTest"
Title="Window1" Height="300" Width="300" FontSize="20" x:Name="window1">
<Window.Resources>
<test:FontSizeConverter x:Key="fontSizeConverter"/>
</Window.Resources>
<Grid>
<StackPanel Grid.Row="0" Grid.Column="0">
<TextBlock
FontSize="{Binding ElementName=window1, Path=FontSize, Converter={StaticResource ResourceKey=fontSizeConverter}, ConverterParameter=1.5}">
Text 1
</TextBlock>
<TextBlock FontSize="{Binding ElementName=window1, Path=FontSize, Converter={StaticResource ResourceKey=fontSizeConverter}, ConverterParameter=0.7}">
Text 2
</TextBlock>
<TextBlock >Text 3</TextBlock>
</StackPanel>
</Grid>
</Window>
ConverterParameter
is used as the scale of the element's font related to the window (specified in ElementName
property of the binding).
In this example font of the first TextBlock
is 150% of the window font and font of the second TextBlock
is 70% of the window. The third TextBlock
follows the font size of the window.
Upvotes: 1