平面按钮样式-当按钮处于活动状态时隐藏边框和焦点提示

如何解决平面按钮样式-当按钮处于活动状态时隐藏边框和焦点提示

我创建了一个带有透明边框的扁平按钮,还设置了FlatAppearance.BorderSize = 0
鼠标单击时边框被隐藏,按下鼠标按钮时,按钮背景使用自定义颜色。

我的问题是,无法删除Button处于活动状态时绘制的边框,例如按下Tab键。
我不能使用TabStop属性(将其设置为false),因为我想要设计的功能

我只想绘制背景颜色并隐藏边框(与鼠标单击颜色相同)。

Picture with the issue

“表单设计器”中的“按钮”属性

this.importBtn.BackgroundImage = global::CompetitionManager.Properties.Resources.Open;
this.importBtn.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Center;
this.importBtn.Cursor = System.Windows.Forms.Cursors.Hand;
this.importBtn.Delta = 5;
this.importBtn.Dock = System.Windows.Forms.DockStyle.Fill;
this.importBtn.FlatAppearance.BorderSize = 0;
this.importBtn.FlatAppearance.MouseDownBackColor = System.Drawing.Color.SteelBlue;
this.importBtn.FlatAppearance.MouSEOverBackColor = System.Drawing.Color.Transparent;
this.importBtn.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.importBtn.ForeColor = System.Drawing.Color.Transparent;
this.importBtn.Location = new System.Drawing.Point(3,50);
this.importBtn.MoveXDirection = false;
this.importBtn.MoveYDirection = true;
this.importBtn.Name = "importBtn";
this.importBtn.Size = new System.Drawing.Size(183,162);
this.importBtn.TabIndex = 0;
this.ToolTip.SetToolTip(this.importBtn,"Import Competitors (Excel/XML)");
this.importBtn.UseMargin = true;
this.importBtn.UseVisualStyleBackColor = true;
this.importBtn.Click += new System.EventHandler(this.ImportFile_Click);

 

解决方法

如问题中所述,自定义控件(此处为按钮)在变成ActiveControl时显示其标准的“焦点提示”。默认渲染似乎不合适,因为“背景”颜色在特定上下文中被渲染为透明,从而导致标准Focus Cue变得令人讨厌。

►禁用了标准的Focus Cue渲染,覆盖了Control.ShowFocusCues,使其始终返回false(尚未创建句柄时除外)。

NotifyDefault方法也被覆盖,以避免在使用Button打开处于活动状态的Windows时产生类似的 effect 效果:在这种情况下,Button使用边框是作为该窗口的ActiveControl的视觉提示。

►使用自定义ControlDesigner从PropertyGrid中删除了一些定义Button specialization 的属性,以避免不必要地篡改特定的 defining 属性。

最后,在自定义控件的ClientRectangle的底部绘制一个自定义Focus Cue,以提供一些 feedback ,否则用户将不知道当前的Button / Control是什么。
当鼠标悬停或单击按钮时,不显示自定义提示。

这是可能的自定义渲染的示例。当然,您现在可以绘制任何内容:不同的 border ,背景,半透明的覆盖层等。

using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Design;
using System.Windows.Forms;
using System.Windows.Forms.Design;

[ToolboxItem(true)]
[DesignerCategory("code")]
[Designer(typeof(CustomDesigner))]
public class ImportButton : Button
{
    private Color m_FocusColor = Color.LightBlue;
    private bool m_DrawFocusCue = false;

    public ImportButton() {
        this.Cursor = Cursors.Hand;
        this.Image = new Bitmap(Properties.Resources.[SomeImage]);
        this.FlatAppearance.BorderSize = 0;
        this.FlatAppearance.MouseDownBackColor = Color.SteelBlue;
        this.FlatAppearance.MouseOverBackColor = Color.Transparent;
        this.FlatStyle = FlatStyle.Flat;
    }

    protected override bool ShowFocusCues {
        get {
            m_DrawFocusCue = !ClientRectangle.Contains(PointToClient(MousePosition));
            return !IsHandleCreated;
        }
    }

    public override void NotifyDefault(bool value) => base.NotifyDefault(false);

    // Make it public if this value should be customizable
    private int FocusBorderSize { get; set; } = 2;

    protected override void OnPaint(PaintEventArgs e) {
        base.OnPaint(e);
        
        if (Focused && m_DrawFocusCue) {
            var rect = ClientRectangle;
            rect.Inflate(-FocusBorderSize,-FocusBorderSize);
            using (var pen = new Pen(FlatAppearance.MouseDownBackColor,FocusBorderSize)) {
                e.Graphics.DrawLine(pen,rect.Bottom,rect.Right,rect.Bottom);
            }
        }
    }

    protected override void Dispose(bool disposing) {
        if (disposing) {
            this.Image?.Dispose();
        }
        base.Dispose(disposing);
    }

    public class CustomDesigner : ControlDesigner
    {
        private static string[] RemovedProperties = new[] {
            "AutoEllipsis","AutoSize","AutoSizeMode","BackColor","Cursor","FlatAppearance","FlatStyle","ForeColor","Text","TextAlign","TextImageRelation"
        };

        public CustomDesigner() { }

        protected override void PreFilterProperties(IDictionary properties) {
            foreach (string prop in RemovedProperties) {
                properties.Remove(prop);
            }
            base.PreFilterProperties(properties);
        }
    }
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?