WPF字体缩放

9
我有一个WPF应用程序,用户界面应该被缩放,这样如果窗口变大,它应该变得更大。在其中一个对话框中,我需要向用户呈现一些项目列表,用户应该点击其中一个。该列表将包含1到约15-20个项目。我希望每个单独项目的字体大小与列表中其他项目的字体大小相同,但同时我希望如果窗口变大,则字体大小也会增加。

目前,我的测试代码如下所示。

<Window x:Class="WpfApplication4.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:controls="clr-namespace:WpfApplication4"
    Title="Window1" Height="480" Width="640">


    <ScrollViewer>

        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="30*" MinHeight="30"/>
                <RowDefinition Height="30*" MinHeight="30"/>
                <RowDefinition Height="30*" MinHeight="30"/>
            </Grid.RowDefinitions>

            <Button Grid.Row="0" MaxHeight="100"><Viewbox><TextBlock>T</TextBlock></Viewbox></Button>
            <Button Grid.Row="1" MaxHeight="100"><Viewbox><TextBlock>Test</TextBlock></Viewbox></Button>
            <Button Grid.Row="2" MaxHeight="100"><Viewbox><TextBlock>Test Longer String</TextBlock></Viewbox></Button>

        </Grid>

    </ScrollViewer>

</Window>

如果应用程序启动并且窗口被放大,一切都看起来很好。如果窗口宽度减小,文本“Test Longer String”的字体大小会变小,但“T”和“Test”的字体大小保持不变。我明白为什么会发生这种情况 - 视图框将内容缩放到其最大尺寸。我想知道的是我应该使用什么方法来解决这个问题。
我不想给控件指定特定的字体大小,因为有些人会在低分辨率屏幕上运行此应用程序,例如640x480,而其他人则会使用更大的宽屏幕。
编辑:
我尝试将代码修改为以下内容:
<ScrollViewer>
    <Viewbox>
        <ItemsControl>
            <Button>Test 2</Button>
            <Button>Test 3</Button>
            <Button>Test 4 afdsfdsa fds afdsaf</Button>
            <Button>Test 5</Button>
            <Button>Test 5</Button>
            <Button>Test 5</Button>
            <Button>Test 5</Button>
            <Button>Test 5</Button>
        </ItemsControl>
    </Viewbox>
</ScrollViewer>

但是随着按钮的尺寸增加,边框也会增加,因此在大屏幕上,按钮边框变得很宽。


对我来说还行 :/ https://i.imgur.com/GXo14Vb.gifv - jeuxjeux20
5个回答

0

如果您只想更改FontSize,则将其绑定到您的MainWindow ActualWidth(例如),并使用转换器进行缩放:

<Window.FontSize>
    <Binding Path="ActualWidth" RelativeSource="{RelativeSource Self}" ConverterParameter="20">
        <Binding.Converter>
            <local:ScaleConverter />
        </Binding.Converter>
    </Binding>
</Window.FontSize>

转换器参数是您在某些任意宽度大小(比如 1000 像素)设置字体大小的方式,您的转换器也会考虑到这一点:

internal class ScaleConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return Double.Parse(parameter.ToString()) * (double)value / 1000;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return Binding.DoNothing;
    }
}

0
这个解决方法可能会有所帮助:
    <ScrollViewer>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="30*" MinHeight="30"/>
            <RowDefinition Height="30*" MinHeight="30"/>
            <RowDefinition Height="30*" MinHeight="30"/>
        </Grid.RowDefinitions>

        <Button Grid.Row="0" MaxHeight="100">
            <Viewbox>
                <TextBlock Width="{Binding ElementName=tbLonger,Path=ActualWidth}">T</TextBlock>
            </Viewbox>
        </Button>
        <Button Grid.Row="1" MaxHeight="100">
            <Viewbox>
                <TextBlock Width="{Binding ElementName=tbLonger,Path=ActualWidth}">Test</TextBlock>
            </Viewbox>
        </Button>
        <Button Grid.Row="2" MaxHeight="100">
            <Viewbox>
                <TextBlock Name="tbLonger">Test Longer String</TextBlock>
            </Viewbox>
        </Button>
    </Grid>
</ScrollViewer>

关键是将所有文本块设置为相同的宽度。在这种情况下,它们都通过绑定跟随最长的文本块。

我相信 OP 的代码在按钮宽度方面没有问题,当窗口变小时它们的长度都相同,但他希望字体大小也相同(或者这是我的理解)。因此,绑定应该与最长文本的字体大小有关。 - Ricardo Olivo Poletti

0

尝试这样做:像平常一样渲染您的文本项:

  • 包含在“ItemsControl”中的TextBlock
  • ListBox

将整个东西放入ViewBox中,并将其设置为根据您的需求进行适当缩放。查找水平、垂直或组合缩放属性。


我已经更新了我的帖子。请看“编辑”下面的内容。简而言之,如果我使用TextBlock而不是Button,则会失去“Button”用户界面(点击效果等)。如果我使用一个Button并将其放置在Viewbox内部,则整个按钮 - 包括其边框 - 将被重新调整大小。我不想要一个1厘米的按钮边框,只因为程序被最大化了。 - Martin

0
我需要制作一个分辨率无关的应用程序,并使用以下答案进行制作: 开发分辨率无关应用程序的技巧 通过这样做,您的应用程序可以根据分辨率进行缩放或缩放。

-1

最简单的方法可能是构建一个装饰器来完成这项工作。您可以将其称为“VerticalStretchDecorator”或类似的名字。

以下是它的使用方法:

<UniformGrid Rows="3" MaxHeight="300">
  <Button>
    <my:VerticalStretchDecorator>
      <TextBlock>T</TextBlock>
    </my:VerticalStretchDecorator>
  </Button> 
  <Button>
    <my:VerticalStretchDecorator>
      <TextBlock>Test</TextBlock>
    </my:VerticalStretchDecorator>
  </Button> 
  <Button>
    <my:VerticalStretchDecorator>
      <TextBlock>Test Longer String</TextBlock>
    </my:VerticalStretchDecorator>
  </Button>
</UniformGrid>

我使用了UniformGrid而不是Grid,但是它们的工作方式是相同的。

实现方式可能类似于这样:

public class VerticalStretchDecorator : Decorator
{
  protected override Size MeasureOverride(Size constraint)
  {
    var desired = base.Measure(constraint);
    if(desired.Height > constraint.Height || desired.Height==0)
      LayoutTransform = null;
    else
    {
      var scale = constraint.Height / desired.Height;
      LayoutTransform = new ScaleTransform(scale, scale); // Stretch in both directions
    }
  }
}

这段代码根本无法编译。Measure()返回void,而MeasureOverride()没有返回值。 - Bob

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接