lundi 10 juin 2019

How to make Winform checkbox ignore DPI setting?

I am trying to make all check boxes in my C# Winform application to ignore user's DPI setting when it's bigger than 100%. i.e I want the size of the checkbox to remain small as if it's on 100% font scale, even when the user has increased the DPI setting.

Using FlatStyle.Flat checkboxes, the size of the checkboxes in various DPI settings:

  • 100% (96 DPI) : 11 pixel x 11 pixel (including border)
  • 125% (120 DPI) : 13 x 13
  • 150% (144 DPI) : 16 x 16

I have done the following but the size of my checkboxes still increases:

  • AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
  • set all Font to use GraphicsUnit.Pixel

So, is there a way for my checkbox to remain 11pixel by 11pixel regardless of DPI setting?

If it's not possible, I have also tried overriding OnPaint on my custom checkbox to paint over the checkbox without painting over the Text. But it proves to be complicated since the starting (X,Y) coordinate to render the box is somewhat affected by CheckAlign and RightToLeft properties.

This is the code snippet. I intended for red box to paint over the original checkbox. And green box as the new checkbox I want to display instead.

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);

            // We need to override checkbox drawing for large font scaling since it will be drawn bigger than usual.
            // ex: At 100% scaling, checkbox size is 11x11. At 125% scaling, checkbox size is 13x13.
            if (e.Graphics.DpiX > 96)
            {
                // What is the x & y co-ords of the checkbox?
                int x = 0;
                int y = 0;

                using (SolidBrush brush = new SolidBrush(Enabled ? Color.White : SystemColors.Control))
                {
                    // Red checkbox is to override the original checkbox drawn
                    var scaleFactor = e.Graphics.DpiX / 96;
                    e.Graphics.DrawRectangle(new Pen(Color.Red), x, y, (float)Math.Round(CHECKBOX_WIDTH * scaleFactor) + 1, (float)Math.Round(CHECKBOX_HEIGHT * scaleFactor) + 1);

                    // Green checkbox is to draw the small checkbox that I want 11x11 (including border)
                    e.Graphics.FillRectangle(brush, x, y, CHECKBOX_WIDTH, CHECKBOX_HEIGHT);
                    e.Graphics.DrawRectangle(new Pen(Color.Green), x, y, CHECKBOX_WIDTH + 1, CHECKBOX_HEIGHT + 1); // Draw the outer border
                }
            }
        }

Can anyone help me how to determine the correct X,Y coord for me to draw the red checkbox, please (so I can paint over the original box).

Thank you :)




Aucun commentaire:

Enregistrer un commentaire