我有一个 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>
但随着按钮边框的尺寸也增加,因此在大屏幕上,按钮边框会变成一厘米宽。
试试这个:像其他时候一样渲染文本项:
TextBlock
包含在“ItemsControl”中?ListBox
?将整个 shebang 放入
ViewBox
中,并将其设置为适合您需要的比例。寻找水平、垂直或组合缩放属性。
此解决方法可能会有所帮助:
<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>
关键是将所有文本块设置为相同的宽度。在这种情况下,它们都通过绑定遵循最长的文本块。
我必须提出一个独立于决议的申请,并在这里给出了这个答案: 开发独立于分辨率的应用程序的技巧
您的应用程序会根据分辨率进行缩放(或缩放)。
如果您只想更改 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;
}
}
最简单的方法可能是构造一个装饰器来完成这项工作。您可以将其称为“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
}
}
}