当按钮大小正确缩放(34×33)时,按钮大小中的图像不会缩放/拉伸/缩放(它仍然是16×16).我做了很多尝试来解决这个问题:
>父控件AutoScaleMode设置为Font,将其设置为Dpi不会使其工作.
>将AutoSize设置按钮设置为true或false不会使其正常工作.
>将按钮或父controlAutoSizeMode设置为任何值都不起作用.
>没有可以设置为拉伸或缩放的Button.ImageLayout.
>使用新的App.Config设置< add key =“EnableWindowsFormsHighDpiAutoResizing”value =“true”/>不起作用.
>更改按钮FlatStyle或ImageAlign不起作用.
你是如何在你的应用中解决这个问题的?
这是代码:
public static IEnumerable<IDisposable> AdjustControlsThroughDPI(this Control.ControlCollection controls) { Debug.Assert(controls != null); if (DPIRatioIsOne) { return new IDisposable[0]; // No need to adjust on DPI One } var list = new List<IDisposable>(); foreach (Control control in controls) { if (control == null) { continue; } var button = control as ButtonBase; if (button != null) { button.AdjustControlsThroughDPI(list); continue; } // Here more controls tahn button can be adjusted if needed... // Recursive var nestedControls = control.Controls; Debug.Assert(nestedControls != null); if (nestedControls.Count == 0) { continue; } var disposables = nestedControls.AdjustControlsThroughDPI(); list.AddRange(disposables); } return list; } private static void AdjustControlsThroughDPI(this ButtonBase button,IList<IDisposable> list) { Debug.Assert(button != null); Debug.Assert(list != null); var image = button.Image; if (image == null) { return; } var imageStretched = image.GetImageStretchedDPI(); button.Image = imageStretched; list.Add(imageStretched); } private static Image GetImageStretchedDPI(this Image imageIn) { Debug.Assert(imageIn != null); var newWidth = imageIn.Width.MultipliedByDPIRatio(); var newHeight = imageIn.Height.MultipliedByDPIRatio(); var newBitmap = new Bitmap(newWidth,newHeight); using (var g = Graphics.FromImage(newBitmap)) { // According to this blog post http://blogs.msdn.com/b/visualstudio/archive/2014/03/19/improving-high-dpi-support-for-visual-studio-2013.aspx // NearestNeighbor is more adapted for 200% and 200%+ DPI var interpolationMode = InterpolationMode.HighQualityBicubic; if (s_DPIRatio >= 2.0f) { interpolationMode = InterpolationMode.NearestNeighbor; } g.InterpolationMode = interpolationMode; g.DrawImage(imageIn,new Rectangle(0,newWidth,newHeight)); } imageIn.Dispose(); return newBitmap; }
请注意,返回了创建的可枚举的一次性位图.如果您不关心在按钮上处理位图,则不必关心处理拉伸位图.
请注意我们处理原始按钮位图.
注意我们自己的成员来处理DPI:MultipliedByDPIRatio(this int),DPIRatioIsOne:bool,s_DPIRatio.你可以写自己的,棘手的一点是获得实际的DPI比率.为了收集DPI比率,我找到的最好的方法是this one.
请注意对博客文章Improving High-DPI support for Visual Studio 2013的引用,其中VS团队解释说,对于他们的图标样式,他们确定图像延伸到200%,100%[最好用Bicubic算法实现,并且高于或等于200%,最好实现与朴素最近邻算法.提供的代码反映了这些选择.
编辑:在200%DPI下的各种插值模式的屏幕截图下,IMHO InterpolationMode.HighQualityBicubic优于InterpolationMode.NearestNeighbor.