Read Only (Visually) CheckBox

I need to have two groups of controls on the screen: inputs and outputs (therefore, they have 2 states: On or Off). Thus, CheckBox seems to be a good choice. Checking any output will install it.

However, when displaying inputs , there will be no user interaction. The user is allowed to see its value, and not change it.

Question: how do checkbos visually appear as read-only?

You might think of possible solutions:

  • Disable CheckBox . Bad: there will be no tooltip (can I solve it? Fake panel on top?) And visually disabling CheckBox not very nice (and I don’t want the user to think that he is disabled).
  • Use a different control. Which one of? Label does not have a good placeholder for the On / Off value. RadioButton look different, but usually they mean that there is one choice from many, and the values ​​of the inputs are independent.
  • Create your own component. Drawing the entire CheckBox went a bit too far (and to be honest, I don't know how to do this in order to have the look of Win7). Is it possible to easily add only the ReadOnly expression in the box field?

What do you guys think?

+7
c # checkbox winforms
source share
7 answers

You have to do it yourself. I think you should use some controls with the correct layout to simulate. Here is a demo code for you, please note that it does not support AutoSize . Since the drawn material is always wider than the default material (which AutoSize works with), it is not easy to implement AutoSize . If you care about AutoSize , this will be great control for you:

 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); } } 

NOTE The code is not fully implemented, everything is as simple as possible. You can change the AlwaysShowCheck property to select the ReadOnly unchecked state, it can be a gray mark or nothing. You can set ReadOnly to true to make it read-only visual.

AlwaysShowCheck set to true (CheckOnly state without a mark is indicated by a gray check mark)

enter image description here

AlwaysShowCheck set to false (a state that is not checked by ReadOnly is indicated by nothing)

enter image description here

+3
source share

There is a solution that is a combination of existing answers.

 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."); 

The result is a CheckBox that

  • disabled with gray text
  • prevents change of value Checked when clicked
  • supports Tooltip
+6
source share

You can provide the listener with a CheckBox click event, as it is possible to cancel your normal thread at run time.

0
source share

While the easiest solution (loans go to ShadowWizard) is to set ForeColor = Color.Gray , it makes the user think that CheckBox disabled.

Compared to Enabled = false , the pros:

  • ToolTip works;
  • The box looks pretty nice (it responds to a mouse hang and is very clearly visible whenever it is checked or not checked).

No cons.

0
source share

In Visual Studio is now available: Properties β†’ Properties β†’ ReadOnly :)

0
source share

There is no need to write the entire control, just write the derivative of "Checkbox". The ReadOnly property has been added to the control, which causes the control to process when it can change its value.

 public class CheckBoxReadOnly : CheckBox { private bool _ReadOnly = false; [DefaultValue(false)] public bool ReadOnly { get { return _ReadOnly; } set { if (_ReadOnly != value) { EventArgs e = new EventArgs(); _ReadOnly = value; OnReadOnlyChanged(e); } } } protected void OnReadOnlyChanged(EventArgs e) { if (ReadOnlyChanged != null) { ReadOnlyChanged(this, e); } } public event ReadOnlyChanged; protected override void OnCheckedChanged(EventArgs e) { static Int16 flag; if (ReadOnly) { flag += 1; if (flag == 1) Checked = !Checked; } else { base.OnCheckedChanged(e); } flag = 0; } } 
0
source share

In the properties table, simply select a selection mode.

-one
source share

All Articles