当按钮大小正确缩放(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.