c# - 开发与分辨率无关的应用程序的技巧

标签 c# wpf resolution-independence

找到工作区测量值并在代码中设置一些属性以便它可以绑定(bind)到 xaml 中控件的边距或高度/宽度属性是否是一个好习惯?

我这样做是为了让我的窗口根据可用的工作区调整大小。

const int w = SystemParameters.WorkArea.Width;
const int h = SystemParameters.WorkArea.Height;

public Thickness OuterGridMargin { get; }

MainViewModel()
{
    OuterGridMargin = new Thickness(w/5,h/6,w/5,h/4);
}

xaml:

<Grid Margin="{Binding OuterGridMargin}" />

我对一些外部容器执行此操作,以便布局不会在较低分辨率下困惑。目前,我在 20"分辨率下使用 1600x900 分辨率(96 dpi)工作。我的应用程序类似于小工具,没有常规窗口。

我想知道是否有一些替代方法。

搜索 [wpf] 分辨率] 1给出了很多解决类似问题的问题,但我仍然卡住了,无法得出结论如何实现良好的分辨率独立布局。

最佳答案

在 WPF 中有两种处理分辨率的方法。

一个选择是设计最小分辨率,并确保所有内容都正确停靠,以便元素随着窗口分辨率变大而变大。这就是很多人在 WinForms 中所做的事情,并且在 WPF 中仍然工作得很好。您可能已经对如何通过设置 Horizo​​ntalAlignment、VerticalAlignment 和边距来处理这个问题有了一些概念。

在 WinForms 中几乎不可能在 WPF 中做的更新、更时髦的事情是让您的应用程序实际上只是放大,这样您的控件就可以像窗口一样变大。为此,您将在 Window 中的某个根元素上应用 ScaleTransform,让 WPF 处理其余部分。这真的很酷。

为了展示它的样子,下面是启动应用程序时窗口的样子,将其变小,然后再变大:http://i.stack.imgur.com/QeoVK.png

这是我制作的小型示例应用程序的代码隐藏:

public partial class MainWindow : Window
{
    public MainWindow() => InitializeComponent();

    #region ScaleValue Depdency 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;
    }

    protected virtual void OnScaleValueChanged(double oldValue, double newValue) { }

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

    private void MainGrid_SizeChanged(object sender, EventArgs e) => CalculateScale();

    private void CalculateScale()
    {
        double yScale = ActualHeight / 250f;
        double xScale = ActualWidth / 200f;
        double value  = Math.Min(xScale, yScale);

        ScaleValue = (double)OnCoerceScaleValue(myMainWindow, value);
    }
}

XAML:

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

关于c# - 开发与分辨率无关的应用程序的技巧,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3193339/

相关文章:

c# - Unity 5.3 WeakReference 的非泛型类型错误

c# - 在 MVVM 中,如果 UI 不需要更新,模型中的属性是否需要属性更改事件?

wpf - ViewBox 是在 WPF 中实现分辨率独立的最佳选择吗?

c# - 如何在 Nunit 中调用 WPF Dispatcher?

wpf - 如何对组合框的 Observable 集合进行排序

apache-flex - 弹性 : Cross resolution applications

xna - 在 XNA 中缩放整个屏幕

c# - 疯狂 VS 设计器错误

c# - ASP.NET 支付表单提交需要指导

c# - 创建一个 Rich Repeater,DataBind 消除自定义添加的控件