是否可以使字体可扩展?

时间:2012-04-15 10:40:04

标签: c# .net wpf fonts scaling

根据窗口大小,我的所有网格都可能很小而且非常大,但内部文字在大网格尺寸上看起来非常小。

我当前的想法(但我不知道如何实现它)是将所有网格元素绑定到单个字体,然后通过

更改字体大小
override void OnRender(DrawingContext dc) {

取决于窗口大小。

问题是:这个想法是否理智,还有其他方法吗?

3 个答案:

答案 0 :(得分:1)

如果您没有明确地在内部元素上设置字体,它们会继承父字体。因此,您可以更改其中一个父元素的字体大小(例如Window本身或Grid)。这会更改未明确指定字体大小的所有内部元素的字体大小。

但是如果您的字体大小不同,我认为最好的解决方案是将元素的字体大小绑定到父窗口的字体大小,并使用值转换器对字体大小进行缩放:< / p>

定义一个像这样的值转换器:

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();
        }
    }
}

并在你的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用作与窗口相关的元素字体的比例(在绑定的ElementName属性中指定)。

在此示例中,第一个TextBlock的字体是窗口字体的150%,第二个TextBlock的字体是窗口的70%。第三个TextBlock遵循窗口的字体大小。

答案 1 :(得分:0)

我更喜欢roberther建议的这个解决方案。它更加干净整洁。

<Viewbox>
    <TextBlock Text="Hello World" />
</Viewbox>

答案 2 :(得分:0)

我知道这是一篇过时的文章,但这是我搜索该主题时首先想到的事情之一,所以这是我的解决方法:

我最近在一个用于处理文本框并相对于屏幕缩放其内容字体大小的项目中完成了此操作。为此,我设置了一个整数值并绑定了字体大小。

对于我来说,我的屏幕高度从800x650开始,我希望字体默认为12号,因此我将整数值(_ScaledFontSize)设置为WindowHeight /(650/12)。

每次屏幕大小更改时,都会调用一个函数来重新计算字体大小,并调用一个属性更改事件。在此函数中,您可以使用以下类似的简单命令添加最小和最大字体大小的约束:

//Set a minimum font size
if(_ScaledFontSize < 12)
    _ScaledFontSize = 12;

为了强制使用此缩放大小,必须将要缩放字体大小的每个控件都绑定到ScaledFontSize属性。

最终结果:

Text at application launch

Text at about 1920x1080 (Slightly smaller because not fullscreen)

一段时间以来,我一直在努力寻找类似的东西,最终这就是我所追求的。幸运的是,代码非常简单: 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>