为什么所有的GUI元素突然有两倍的高度和宽度?

时间:2013-08-07 13:49:34

标签: visual-studio-2008 compact-framework screen-resolution

我开发了一个控件,根据Height定位子元素。当我使用模拟器测试时,一切正常,但在实际设备上,我必须使用(Height * 2)来正确定位。

除此之外,16x16的图标在仿真器中看起来很好,但在实际设备上放大了很多,因为PictureBox突然有两倍的高度和宽度。

这种有线现象发生在我测试应用程序的所有设备上。

这是否与移动设备的屏幕分辨率有关? 导致此问题的原因是什么?如何解决此问题?

编辑: 以下是计算元素下一个位置的代码。注释掉的代码适用于设备,但不适用于模拟器。

    private Point GetNextUserControlLocation(Control control)
    {
        var numberOfControls = Controls.Count;
        if (numberOfControls < 1)
            return new Point(1, 1);

        var latest = Controls[numberOfControls - 1];
        var x = latest.Location.X;
        // var y = latest.Location.Y + control.Height * 2 + 1;
        var y = latest.Location.Y + control.Height + 1;

        return new Point(x, y);
    }

2 个答案:

答案 0 :(得分:2)

听起来问题是您的设备的分辨率与仿真器不同,即使屏幕尺寸相同。我知道一些较新的设备(特别是来自摩托罗拉)有640x480的屏幕分辨率而不是标准的320x240。

你应该做两件事来解决它。对于您在设计级别进行的定位,只需将表单的AutoScaleMode属性设置为System.Windows.Forms.AutoScaleMode.Dpi即可。这导致表单使用DPI作为基线来正确定位设计器中布置的所有内容。如果您的设备的屏幕分辨率是仿真器的2倍,您将看到设备上所有子控件的高度和宽度都加倍。

对于手动定位,你需要做一些数学运算。 .NET CF使用96 DPI作为测量基准,因此当屏幕DPI = 96时,则1个单位= 1个像素。您可以通过将设备的DPI与96进行比较来正确确定缩放单位的数量。

要计算设备的屏幕DPI,请使用以下P / Invokes:

    [DllImport("coredll.dll", EntryPoint = "GetDC", SetLastError = true)]
    public static extern IntPtr GetDC(IntPtr hWnd);

    [DllImport("coredll.dll", SetLastError = true)]
    public static extern int GetDeviceCaps(IntPtr hDC, int nIndex);

    [DllImport("coredll.dll", SetLastError = true)]
    public static extern void ReleaseDC(IntPtr hDC);

    private const int LOGPIXELSX = 88;
    private const int LOGPIXELSY = 90;

这是一个辅助函数的摘录,用于获取X和Y方向的标量值:

            //get handle to desktop
            IntPtr hDC = GetDC(IntPtr.Zero);

            try
            {
                if (hDC != IntPtr.Zero)
                {
                    int logPixelX = GetDeviceCaps(hDC, LOGPIXELSX);
                    int logPixelY = GetDeviceCaps(hDC, LOGPIXELSY);

                    _scaleX = (float)logPixelX / 96.0f;
                    _scaleY = (float)logPixelY / 96.0f;
                }
            }
            finally
            {
                if (hDC != IntPtr.Zero)
                    ReleaseDC(hDC);
            }

将其包装到类中,添加ScaleX和ScaleY函数,您可以使用scaleX和scaleY的值来调整您的位置。您的定位代码现在看起来像:

    var y = latest.Location.Y + control.Height + UICoordinateScalar.ScaleY(1);

希望有所帮助!

答案 1 :(得分:1)

当你加倍时控件是否正确尺寸?我假设你正在使用像素作为你的尺码元素,如果你试图在PictureBoxes上获得特定的分辨率,当然如果你使用积分或英寸,你的里程绝对会有所不同。

如果控件的尺寸合适,或者符合您所期望的参数,但定位最终会出现在错误的位置,那么您应该重新确定如何定位它(代码为哪个)我建议穿上这里!)。