C#控件位置精度

4

我需要在表单上放置控件时,需要比整数位置更高的精度。似乎控件位置只支持Point类型。是否有解决方法?

Point p = new Point(100, 200); this.Location = p; // 当然这个可以工作

PointF pF = new PointF(100.04f, 200.08f); this.Location = pF; // 当然这个不行,因为Location期望一个Point而不是PointF

是否有一些设置可以在基础表单或基础控件上进行,以获得更高的位置精度?

4个回答

4
你可以使用 Windows Presentation Foundation(WPF)和 XAML(两者在Visual Studio中都能很好地工作),这允许对控件进行亚像素定位。
然而,假设你正在使用Windows Forms而不是WPF,为什么需要将控件放在非整数(亚像素)位置上呢?

是的,我正在使用Windows表单而不是WPF。我有一个基于打印机像素300x300 dpi的外部文件格式,用于文本位置。因此,如果我有一台运行在96dpi的Windows机器,并且文件位置为281,281,则我的Windows表单位置为(281/3.125)= 89.92。如果我不必将任何更改保存回300x300 dpi格式文件,那就没什么大不了的,但我必须这样做。而且我必须允许用户将控件移动到新位置。 - AC.
你为什么需要在WPF中将控件放置在非整数(子像素)位置上? - MusiGenesis

1

不,WinForms中的控件渲染基本上都是基于像素的。有一种方法可以实现子像素定位(不使用WPF),但这需要你付出努力,而且我真的不确定为什么你需要这个。

这种方法的要点是创建一个用户控件,其中包含一个你想要放置在奇怪位置(可能是子像素)的控件的隐藏实例。你将所有用户控件的事件连接到隐藏控件,每次事件传递后,你调用隐藏控件的DrawToBitmap方法来获取控件的快照。然后,你使用Graphics.DrawImage将快照复制到用户控件的表面。DrawImage不限于像素,因此你可以通过小于一个像素的偏移量来实现精确的定位。

警告:请不要真的这样做,因为你可以使用WPF。这将是一项巨大的工作,因为“通过控件的事件传递”并不像听起来那么简单。在这种方式下,正确呈现焦点也存在问题,因为不可见的控件无法获得焦点(我甚至不会告诉你解决这个问题的可怕黑客方法)。

更新:重新考虑使用WPF的决定是值得的-它非常适合你正在做的事情,并且会让你的生活变得更加简单。我对WPF的印象一般,因为我认为虽然它非常强大,但它本质上对于它最常用的用途(即无聊的商业应用程序)而言过于强大了。但在你的情况下,它提供了你实际需要的细粒度。

如果你在WinForms中遇到困难,最好的方法是编写自己的 UserControl 版本的文本编辑控件。核心上,一个 TextBox 只是一个你可以画一个边框和一些文本的正方形。.Net的 Graphics 方法(DrawRectangleDrawString)可以指定浮点坐标进行绘制。

关于所有者绘制用户控件和GDI+图形,有大量的StackOverflow问题。


我有一个基于打印机像素300x300 dpi的外部文件格式,用于文本定位。因此,如果我有一台运行在96dpi的Windows机器,并且文件位置是281,281,则我的Windows表单位置为(281/3.125) = 89.92。如果我不必将任何更改保存回300x300 dpi格式文件,那就没什么大不了的,但我必须这样做。而且我必须允许用户将控件移动到新位置。 - AC.
感谢提供信息,很高兴知道WPF可以解决这个问题,但是该项目必须使用Windows Forms。我必须想办法解决这个问题。如果我能将Windows电脑的dpi更改为96或120以外的其他值,那就太好了,100 dpi会很棒。 - AC.
如果我可以将Windows计算机的dpi更改为96或120以外的其他值,那将是很好的事情,如果我可以使用100 dpi就更好了。但是忘记这部分,那也没有帮助... :( - AC.
AC:我不太明白你在做什么。你是在将控件(文本框、组合框等)叠加在可打印表单的图像上,然后尝试将控件中的内容打印到实际的表单副本上吗? - MusiGenesis
如果您只是想在比像素更精确的位置上将文本呈现为位图,那么这很容易实现。 - MusiGenesis
打印表单设计器,读取一个文件,该文件具有基于300x300 dpi的精确放置位置信息。因此,在文件中有关文本值和线值的信息,我需要在屏幕上显示它们并允许用户移动它们并添加其他内容,然后保存回该文件格式。 - AC.

1

尽管GDI+具有浮点坐标系统的能力,但基于Win32(Winforms所基于的平台)的坐标系统却没有这种能力。我赞成建议转移到WPF,它具有基于设备无关虚拟像素的普遍浮点坐标系统。


0

1点等于1像素,因此需要的最大分辨率。

这就是为什么在1024x768的分辨率中,0,0映射到左上角,而1024映射到右上角的原因。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接