views:

107

answers:

4

I need more precision then integer based locations when puttng controls on a form. It seems control.location only supports Point. Is there a work around for this?

Point p = new Point(100, 200); this.Location = p;// this works of course

PointF pF = new PointF(100.04f, 200.08f); this.Location = pF;// this does not work of course because Location expects a Point not PointF

Is there some setting on the base form, or base control I can set to have more location precision?

A: 

1 point is 1 pixel and therefore the maximum resolution required.

This is the reason why 0,0 maps to the left corner, and 1024 maps to the right, in a resolution of 1024x768

SLC
+3  A: 

You could use Windows Presentation Foundation (WPF) together with XAML (both work nicely within Visual Studio), which allows subpixel positioning of controls.

However, assuming that you are using Windows Forms and not WPF, why would you ever need to put a control on a non-integer (subpixel) location?

Virtlink
Yes I'm using windows forms not WPF. I have an external file format that is based on printer pixels 300x300 dpi for text location. So if I have a windows machine running at 96dpi, and the file location is 281,281 then my windows forms position is (281/3.125) = 89.92. Not a big deal if I did not have to save any changes back to the 300x300 dpi format file, but I do. And I have to allow users to move the controls around to new locations.
AC
Why would you ever need to put a control on a non-integer (subpixel) location in WPF?
MusiGenesis
Never mind - I assume that's to facilitate smooth animation.
MusiGenesis
+1  A: 

No, control rendering in WinForms is all fundamentally pixel-based. There is a way you could achieve sub-pixel positioning (without using WPF), but it would be work on your part, and I'm really not sure why you would need this anyway.

The gist of the approach is to create a user control with a hidden instance of the control you're trying place funkily (sub-pixelly, maybe). You wire up all the user control's events so that they pass through to the hidden control, and after each event is passed you call the hidden control's DrawToBitmap method to get a snapshot of the control. You then use Graphics.DrawImage to copy the snapshot to the surface of the user control. DrawImage is not restricted to pixels, so you can offset the drawing by less than a pixel to achieve the precise positioning you're looking for.

Warning: please do not actually do this, as there is no reason for it when you can just use WPF. This would be a lot of work, since "passing the control's events through" is not as simple matter as it sounds. There's also a problem with rendering the focus correctly in this manner, as the invisible control cannot be given the focus (I'm not even going to tell you what the grisly hack solution is to that problem).

Update: It's worth revisiting that decision about WPF - it is ideal for what you're doing and would make your life much simpler. I have been generally underwhelmed by WPF, because I think that while it's very powerful it is essentially overpowered for the uses to which it is most often put (namely, boring-ass business apps). In your case, though, it provides a granularity that you actually require in your app.

If you're stuck in WinForms, however, your best approach is to write your own UserControl versions of the text-editing controls that your application requires. At its core, a TextBox is just a square that you draw a border around and some text on. The .Net Graphics methods for this (DrawRectangle and DrawString) can have the drawing coordinates specified in floating point.

There are tons of StackOverflow questions about owner-drawn user controls and GDI+ graphics.

MusiGenesis
I have an external file format that is based on printer pixels 300x300 dpi for text location. So if I have a windows machine running at 96dpi, and the file location is 281,281 then my windows forms position is (281/3.125) = 89.92. Not a big deal if I did not have to save any changes back to the 300x300 dpi format file, but I do. And I have to allow users to move the controls around to new locations.
AC
thanks for the info, nice to know WPF will solve this issue, but Windows Forms was a mandate of the project. I will have to deal with the issue some way. It would be nice if I could change my windows computer dpi to something other than 96 or 120, if I could 100 dpi would be great.
AC
It would be nice if I could change my windows computer dpi to something other than 96 or 120, if I could 100 dpi would be great. Forget that part, that would not help either.. :(
AC
AC: I don't quite follow what you're doing. Are you doing something like superimposing controls (textboxes, comboboxes etc.) over an image of a printable form, and you're trying to print out what's in the controls onto a real copy of the form?
MusiGenesis
If you're just trying to render text to a bitmap in locations more precise than a pixel, then that's easy to do.
MusiGenesis
print form designer that reads in a file that has exact placement location info based on 300x300 dpi. So in the file is info about text values and line values, that I need to show on the screen and allow a user to move them around and add others, and then save back to that file format.
AC
+1  A: 

Although GDI+ is capable of floating point coordinate systems, Win32 (upon which Winforms is based) is not. I second the reccomendation to move to WPF which has a ubiquitous floating point coordinate system based on device independent virtual pixels.

Josh Einstein