Reputation: 33
I've been writing a custom drawn tab control for a few days now and for the most part everything is pretty and it does an amazing job ... except when I use it on my Windows 10 computer (at run-time).
I've gone back to the most basic few lines of code to trace the error and I can't for the life of me figure this out.
Below is the only code being used, in a nutshell I'm designing a horizontal aligned tab control.
using System.Drawing;
using System.Windows.Forms;
namespace WindowsFormsApplication1.UI
{
class TabControlTest : TabControl
{
public TabControlTest()
{
Alignment = TabAlignment.Left;
SizeMode = TabSizeMode.Fixed;
}
}
}
I've simply added the custom tab control to the form, added a couple of group boxes for reference purposes and changed the background colour of the form to grey so you can clearly see the tab control.
Now, at design time the 2 group boxes (1 in the tab control, 1 on the form) align perfectly.
But at run-time I see a very different result.
As you can see the tab part of the control is now larger than it was at design time and the resulting change means the contexts of the tab have also moved.
If I do this on a Windows 7 computer everything is displayed as it appears at design time, as it should!
I've added ImageSize but it makes no difference.
ItemSize = new System.Drawing.Size(30, 150);
I've reinstalled VS on my (Win10) development machine. I'm at a loss to explain why and how to resolve this.
Any/all help would be immensely appreciated.
Upvotes: 3
Views: 785
Reputation: 1151
Looking at your tab width in your comparison images, I believe this is another issue caused by automatic Windows control scaling. I found that it is the dpiAware option is automatically set when it's run from within Visual Studio and then reverts back to the default Windows Scaling that windows Implements when outside Visual Studio.
To prevent that auto-scaling when run outside Visual Studio altogether you need to Notify the OS that you're application is dpiAware by calling the Win32 P/Invoke SetProcessDPIAware() method from within your Main() before Application.Run() is called, like the example below demonstrates. This will let your controls use the native resolution which your designing the coordinates from.
static class Program
{
[System.Runtime.InteropServices.DllImport("user32.dll")]
private static extern bool SetProcessDPIAware();
static void Main(string[] args)
{
if (Environment.OSVersion.Version.Major >= 6)
SetProcessDPIAware();
Application.Run(new UIMonitor());
}
}
Alternatively, if you want to keep the scaling, you may be able to set the GroupBox location based off the Width of the Tab Control instead of a specific location. (Or by using some combination of Control measurements instead of exact picel placement.)
Upvotes: 2