只读(可视)CheckBox

Sin*_*atr 8 c# checkbox winforms

我需要在屏幕上有两组控件:输入输出(因此它们有2种状态:).因此CheckBox似乎是一个不错的选择.检查任何输出将设置它.

但是,在显示输入时,将不会与用户进行任何交互.用户只能看到它的值,而不是更改它.

问题:如何使checkbos在视觉上显示为只读

可以考虑可能的解决方案:

  • CheckBox禁用.坏:没有工具提示(可以解决它?通过假面板在顶部?)和视觉禁用CheckBox不好(我不想让用户认为它被禁用).
  • 使用不同的控制.哪一个?Labelon/Off值没有好的占位符.RadioButton看起来不一样,但它们通常意味着有许多选择,而输入值是独立的.
  • 制作自己的组件.绘制整体CheckBox有点矫枉过正(老实说,我不知道怎么做才能让Win7出现).是否可以ReadOnly轻松地仅在箱子部件中添加外观?

你们有什么感想?

Ed *_*pel 9

有一个解决方案是现有答案的组合.

checkBox.ForeColor = Color.Gray; // Read-only appearance
checkBox.AutoCheck = false;      // Read-only behavior

// Tooltip is possible because the checkbox is Enabled
var toolTip = new ToolTip();
toolTip.SetToolTip(checkBox, "This checkbox is read-only.");
Run Code Online (Sandbox Code Playgroud)

结果就是CheckBox这样

  • 显示已禁用灰色文本
  • Checked单击时可防止更改值
  • 支持一个 Tooltip


Kin*_*ing 3

你必须自己画一切。我认为你应该使用一些布局正确的控件来模仿它。这是给您的演示代码,请注意,它不能正确支持AutoSize。因为绘制的东西总是比默认的东西(可以使用AutoSize)宽,所以实现起来AutoSize并不容易,如果你不太关心AutoSize,这对你来说将是一个很好的控制:

public class XCheckBox : CheckBox
{        
    public XCheckBox()
    {            
        SetStyle(ControlStyles.Opaque, false);
        ReadOnlyCheckedColor = Color.Green;
        ReadOnlyUncheckedColor = Color.Gray;
    }        
    public bool ReadOnly { get; set; }
    public bool AlwaysShowCheck { get; set; }
    public Color ReadOnlyCheckedColor { get; set; }
    public Color ReadOnlyUncheckedColor { get; set; }
    protected override void OnPaint(PaintEventArgs pevent)
    {
        if (ReadOnly)
        {
            pevent.Graphics.SmoothingMode = SmoothingMode.HighQuality;
            pevent.Graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
            if (AlwaysShowCheck || Checked)
            {
                RenderCheck(pevent.Graphics);
            }
            RenderText(pevent.Graphics);                
        }
        else base.OnPaint(pevent);                            
    }
    private void RenderCheck(Graphics g)
    {
        float fontScale = Font.Size / 8.25f;   
        Size glyphSize = CheckBoxRenderer.GetGlyphSize(g, System.Windows.Forms.VisualStyles.CheckBoxState.CheckedNormal);            
        glyphSize.Width = (int) (glyphSize.Width * fontScale);
        glyphSize.Height = (int)(glyphSize.Height * fontScale);            
        string checkAlign = CheckAlign.ToString();
        using (GraphicsPath gp = new GraphicsPath())
        using (Pen pen = new Pen(Checked ? ReadOnlyCheckedColor : ReadOnlyUncheckedColor, 1.5f)
        {
            LineJoin = LineJoin.Round,
            EndCap = LineCap.Round,
            StartCap = LineCap.Round
        })
        {
            gp.AddLine(new Point(3, 7), new Point(5, 10));
            gp.AddLine(new Point(5, 10), new Point(8, 3));
            float dx = checkAlign.EndsWith("Right") ? Math.Max(-4*fontScale, ClientSize.Width - glyphSize.Width - 4 * fontScale) :
                     checkAlign.EndsWith("Center") ? Math.Max(-4*fontScale, (ClientSize.Width - glyphSize.Width) / 2 - 4 * fontScale) : -4;
            float dy = checkAlign.StartsWith("Bottom") ? Math.Max(-4*fontScale, ClientSize.Height - glyphSize.Height - 4*fontScale) :
                     checkAlign.StartsWith("Middle") ? Math.Max(-4*fontScale, (ClientSize.Height - glyphSize.Height) / 2 - 4*fontScale) : 0;

            g.TranslateTransform(dx, dy);
            g.ScaleTransform(1.5f*fontScale, 1.5f*fontScale);
            g.DrawPath(pen, gp);
            g.ResetTransform();                
        }
    }
    private void RenderText(Graphics g)
    {
        Size glyphSize = CheckBoxRenderer.GetGlyphSize(g, System.Windows.Forms.VisualStyles.CheckBoxState.CheckedNormal);
        float fontScale = Font.Size / 8.25f;
        glyphSize.Width = (int)(glyphSize.Width * fontScale);
        glyphSize.Height = (int)(glyphSize.Height * fontScale);
        string checkAlign = CheckAlign.ToString();
        using (StringFormat sf = new StringFormat())
        {
            string alignment = TextAlign.ToString();
            sf.LineAlignment = alignment.StartsWith("Top") ? StringAlignment.Near :
                               alignment.StartsWith("Middle") ? StringAlignment.Center : StringAlignment.Far;
            sf.Alignment = alignment.EndsWith("Left") ? StringAlignment.Near :
                           alignment.EndsWith("Center") ? StringAlignment.Center : StringAlignment.Far;
            sf.FormatFlags = StringFormatFlags.NoWrap | StringFormatFlags.NoClip;
            Rectangle textRectangle = ClientRectangle;
            if (checkAlign.EndsWith("Left"))
            {
                textRectangle.Width -= glyphSize.Width;
                textRectangle.Offset(glyphSize.Width, 0);
            }
            else if (checkAlign.EndsWith("Right"))
            {
                textRectangle.Width -= glyphSize.Width;
                textRectangle.X = 0;
            }
            g.DrawString(Text, Font, new SolidBrush(ForeColor), textRectangle, sf);
        }
    }        
    bool suppressCheckedChanged;
    protected override void OnClick(EventArgs e)
    {
        if (ReadOnly) {
            suppressCheckedChanged = true;
            Checked = !Checked;
            suppressCheckedChanged = false;
        }
        base.OnClick(e);
    }
    protected override void OnCheckedChanged(EventArgs e)
    {
        if (suppressCheckedChanged) return;
        base.OnCheckedChanged(e);
    }        
}
Run Code Online (Sandbox Code Playgroud)

注意:代码尚未完全实现,一切都尽可能简单。您可以更改AlwaysShowCheck属性以选择ReadOnly未选中状态,它可以是灰色勾号什么都没有。您可以将其设置ReadOnlytrue只读视觉

AlwaysShowCheck设置为true(ReadOnly 未选中状态由灰色勾号表示)

在此输入图像描述

AlwaysShowCheck设置为false(ReadOnly 未选中状态不表示任何内容)

在此输入图像描述