WPF 字体缩放

发布于 2024-08-10 14:30:34 字数 2250 浏览 3 评论 0原文

我有一个 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 的字体大小会变小,但 TTest 的字体大小保持不变相同。我确实理解为什么会发生这种情况 - 视图框会将内容缩放到其最大尺寸。我想知道的是我应该用什么方法来解决这个问题。

我不想为控件提供特定的字体大小,因为有些人会在低分辨率屏幕(例如 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>

但是随着按钮边框的大小也增加,因此在大屏幕上,按钮边框变为一厘米宽。

I have a WPF application where the user interface should be scaled so that it should become larger if the windows is made larger. In one of the dialogs, I need to present a list of items to a user and the user should click one of them. The list will contain from 1 to around 15-20 items. I want the font size for each individual item to be as big as the font size for the other items in the list, but at the same time I want the font size to increase if the window is made larger.

At the moment, my test code looks like below.

<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>

If the application is started and the Window is made wide, everything looks OK. If the window width is decreased, the font size of the text Test Longer String is made smaller, but the font size for T and Test remains the same. I do understand why this happens - the viewbox will scale the contents to its maximum size. What I want to know is what method I should use to solve this problem.

I don't want to give the controls specific font sizes because some people will run this on low-resolution screens such as 640x480 and others will use larger widescreens.

EDIT:

I've tried to modify my code to the following:

<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>

But with the size of the button borders are increased as well, so on large screens, the button borders become a centimeter wide.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

他不在意 2024-08-17 14:30:35

如果您只想更改 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;
    }
}

If you only want the FontSize to change then bind it to your MainWindow ActualWidth (say) and use a converter to scale:

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

The converter parameter is how you set the font size at some arbitrary width size (1000 pixels, say), which your converter will then also take into account:

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;
    }
}
起风了 2024-08-17 14:30:35

最简单的方法可能是构建一个装饰器来完成这项工作。您可以将其称为“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,但它与 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
    }
  }
}

The simplest way is probably to construct a decorator to do the job. You might call it "VerticalStretchDecorator" or something like that.

Here is how it would be used:

<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>

I used UniformGrid instead of Grid, but it would work the same way with Grid.

It would be implemented something like this:

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
    }
  }
}
绅士风度i 2024-08-17 14:30:34

试试这个:像其他时候一样渲染文本项:

  • “ItemsControl”中包含 TextBlock 吗?
  • 列表框

将整个 shebang 放入 ViewBox 中,并将其设置为适合您需要的缩放比例。寻找水平、垂直或组合缩放属性。

Try this: Render your text items like you would do it any other time:

  • TextBlocks contained in an 'ItemsControl'?
  • ListBox?

Place the whole shebang into a ViewBox and set it to scale appropriate to your needs. Look for Horizontal, Vertical or combined scaling properties.

画骨成沙 2024-08-17 14:30:34

此解决方法可能会有所帮助:

    <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>

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

This workaround might help:

    <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>

The key is to set all textblocks the same width. In this case they all follow the longest textblock through binding.

方觉久 2024-08-17 14:30:34

我必须制作一个独立于决议的应用程序,并在此处使用以下答案:
开发与分辨率无关的应用程序的提示

,您的应用程序正在缩放(或缩放) ,取决于分辨率。

I had to make an resolution independent application and made it with this answer here:
tips on developing resolution independent application

with that your application is scaling (or zooming), depending on the resolution.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文