0

我正在尝试动态缩放基于 WPF 的应用程序的 UI,我想使用当前分辨率与本机分辨率的比率,如下所示:

    <Grid.LayoutTransform>
        <ScaleTransform CenterX="0" CenterY="0" ScaleX="{Binding FormWidth/NativeREsolution}" ScaleY="{Binding FormWidth/NativeREsolution}"/>
    </Grid.LayoutTransform>

我发现缩放变换的原因是它缩放了容器内的所有 UI 元素,包括框架和子页面。

有没有办法做到这一点?

或者,是否有更好的方法来根据窗口大小动态缩放应用程序?

4

2 回答 2

2

WPF 本质上是独立于分辨率的。

<Window ..>
   <Grid>

   <!-- Content here -->

   </Grid>
</Window>

上面的 XAML 将导致Grid拉伸到窗口大小。不需要可怕的类似winforms的黑客攻击。

编辑:

如果您希望Everything(包括字体大小)在 a 内缩放Window,只需使用 Viewbox:

<Window>
   <Viewbox>
       <Grid>

       <!-- Content here -->

       </Grid>
   </Viewbox>
</Window>
于 2013-09-16T16:14:34.633 回答
0

最简单的解决方案是使用 Viewbox,但也可以非常简单地计算 Window resize 的比例。

视图框

<Window x:Class="MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
<Viewbox Stretch="Uniform">
    <Grid>
        <Label>
            Hello world
        </Label>
    </Grid>
</Viewbox>
</Window>

手动缩放

<Window x:Class="WpfApplication1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" 
    Name="myMainWindow"
    Width="200" Height="250">
<Grid Name="MainGrid" SizeChanged="MainGrid_SizeChanged">
    <Grid.LayoutTransform>
        <ScaleTransform x:Name="ApplicationScaleTransform"
                        CenterX="0"
                        CenterY="0"
                        ScaleX="{Binding ElementName=myMainWindow, Path=ScaleValue}"
                        ScaleY="{Binding ElementName=myMainWindow, Path=ScaleValue}" />
    </Grid.LayoutTransform>
    <Grid VerticalAlignment="Center" HorizontalAlignment="Center" Height="150">
        <TextBlock FontSize="20" Text="Hello World" Margin="5" VerticalAlignment="Top" HorizontalAlignment="Center"/>
        <Button Content="Button" VerticalAlignment="Bottom" HorizontalAlignment="Center"/>
    </Grid>
</Grid>

其中网格使用 LayoutTransform 进行缩放,该 LayoutTransform 通过引用编码的 ScaleValue 依赖属性来确定 ScaleX 和 ScaleY 属性,该属性是在 Window_Resize 事件期间使用类似于类似的代码计算的

#region ScaleValue Dependency Property

    public static readonly DependencyProperty ScaleValueProperty = DependencyProperty.Register("ScaleValue", typeof(double), typeof(MainWindow), new UIPropertyMetadata(1.0, new PropertyChangedCallback(OnScaleValueChanged), new CoerceValueCallback(OnCoerceScaleValue)));

    private static object OnCoerceScaleValue(DependencyObject o, object value)
    {
        MainWindow mainWindow = o as MainWindow;
        if (mainWindow != null)
            return mainWindow.OnCoerceScaleValue((double)value);
        else
            return value;
    }

    private static void OnScaleValueChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
    {
        MainWindow mainWindow = o as MainWindow;
        if (mainWindow != null)
            mainWindow.OnScaleValueChanged((double)e.OldValue, (double)e.NewValue);
    }

    protected virtual double OnCoerceScaleValue(double value)
    {
        if (double.IsNaN(value))
            return 1.0f;

        value = Math.Max(0.1, value);
        return value;
    }

    public double ScaleValue
    {            
        get
        {
            return (double)GetValue(ScaleValueProperty);
        }
        set
        {
            SetValue(ScaleValueProperty, value);
        }
    }
    #endregion


    private void CalculateScale()
        {
            double yScale = ActualHeight / 250f;
            double xScale = ActualWidth / 200f;
            double value = Math.Min(xScale, yScale);
            ScaleValue = (double)OnCoerceScaleValue(MainGrid, value);
        }
于 2013-09-16T16:37:57.627 回答