Here's the scenario: I am coding a program that will display data from a database in a variety of fields. Some of the fields need to be read-only. Should have been simple just to set all those controls to read-only, except some of them are checkboxes, radio buttons and date pickers, which do not support a read-only setting. I could mark them disabled, but that changes the color on the controls, and overriding the colors is more complicated than I want to do. So the solution that I'm trying to implement is to cause an empty label (or other control) to be transparent, so it can sit on top of the read-only controls and prevent interaction. I found the following article (http://msdn.microsoft.com/en-us/library/wk5b13s4.aspx) which says you can do this with just two lines in the control's constructor:

SetStyle(ControlStyles.SupportsTransparentBackColor, true);
this.BackColor = Color.Transparent;

Seems simple enough, but I don't know where to put this. I haven't messed with constructors in C#.NET, and when I did them in C++ it was quite some time ago (and not visual). My Google searches so far have yielded only info about custom class constructors, not modifying a control. Any help here would be great. I'm hoping it will just be a quick "the constructors are here" kind of answer. If you've tried this and know that what I'm trying to accomplish won't work, that's OK too (I have a couple "plan B" options, I just don't like them). I'm also totally open to completely different methods of making the controls read-only, if you have any.

I'm pretty new to C# and this is my first post here, so please be nice. :)

Recommended Answers

All 9 Replies

You can do it in the form.designer.cs file, along with all the other attributes that are set there in the InitializeComponent method.

You can do it in the form.designer.cs file, along with all the other attributes that are set there in the InitializeComponent method.

Can you give me more details? There are several places that my "transparent" control is referenced in that method. I would assume that it belongs in (or just below) this section:

// 
// TransparentCancelledHtcLabel
// 
this.TransparentCancelledHtcLabel.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(1)))), ((int)(((byte)(204)))), ((int)(((byte)(212)))), ((int)(((byte)(1)))));
this.TransparentCancelledHtcLabel.Location = new System.Drawing.Point(0, 91);
this.TransparentCancelledHtcLabel.Name = "TransparentCancelledHtcLabel";
this.TransparentCancelledHtcLabel.Size = new System.Drawing.Size(60, 37);
this.TransparentCancelledHtcLabel.TabIndex = 36;

And I had tried putting the code there, but it doesn't work the way MSDN explains it. I can enter the first line more or less like it appears in MSDN:

SetStyle(System.Windows.Forms.ControlStyles.SupportsTransparentBackColor, true);

It requires a more fully qualified version of "ControlStyles", but OK. However, the 2nd line won't work at all. If I enter this.Backcolor = there is no Color. option. Besides, nothing in either of these lines indicates that it is going to that label specifically. I would have assumed it needed to be somewhere within {braces} or something so it would only belong to that control. I tried entering this.TransparentCancelledHtcLabel. but "SetStyle" doesn't exist for that context.

Believe me I'm a nice guy :)
Just wondering...(I'm a sort of user interface guy) (Not GUI please!!!)
My question: why would you show info from a DB in the form of checkboxes and radiobuttons? These UI objects are meant to be interactive with the user, so why make them readonly?

Believe me I'm a nice guy :)
Just wondering...(I'm a sort of user interface guy) (Not GUI please!!!)
My question: why would you show info from a DB in the form of checkboxes and radiobuttons? These UI objects are meant to be interactive with the user, so why make them readonly?

Fair question. :)
There are two reasons. First, is because basically what I am doing now is recreating a very old program for one of our departments because they need some updates to it and the source code is not available (and was in a language we don't support). It was this way in the old program, so I am attempting to minimize the differences when we transition them to the new one.
Second, the program has active and cancelled data components--active can be changed, cancelled cannot. Because they are identical fields, they would like to be able to compare apples to apples when looking at the active vs. cancelled data. That way, when they see the active field [x] Letter received, they won't see Letter received [true] down in the cancelled version.

Add this code to your form:

private Boolean userCheck = true;
private void checkBox_CheckedChanged(object sender, EventArgs e) {
    if (userCheck) {
        userCheck = false;
        ((CheckBox)sender).Checked = !((CheckBox)sender).Checked;
        userCheck = true;
    }
}

Before you set the status of the checkboxes make sure you set userCheck to false. Change the values based on your database settings, then set userCheck back to true. Subscribe all your checkboxes to this event. You can do something similar to all the radiobuttons but you'll need to save their states.

commented: Found a different method to fix the original problem, but this post helped me in other areas of my application. +1

Add this code to your form:

private Boolean userCheck = true;
private void checkBox_CheckedChanged(object sender, EventArgs e) {
    if (userCheck) {
        userCheck = false;
        ((CheckBox)sender).Checked = !((CheckBox)sender).Checked;
        userCheck = true;
    }
}

Before you set the status of the checkboxes make sure you set userCheck to false. Change the values based on your database settings, then set userCheck back to true. Subscribe all your checkboxes to this event. You can do something similar to all the radiobuttons but you'll need to save their states.

Just to be sure I understand what your code is doing: if userCheck is true (meaning the user is the one doing the changing) then the code just "undoes" the checking action. Correct? That is kind of what I was thinking of as a "plan B" if I can't get the transparent label to work (your code is probably simpler than what I would have come up with :)). I'm still curious about updating the constructor, if nothing more than so I know how to use it for future reference. Do you know how to modify the constructor so it will work like MSDN says? I played with it some more and still can't get anything close to their code to insert properly within the InitializeComponent() method.

They are referring to user created controls, not the ones built into .NET. You'd have to derive your own control to do what they are talking about.

As for the above code, you are correct. You need the boolean otherwise when you undo the checking, it causes a CheckChanged event which attempts to undo the checking which causes a CheckChanged event which attempts to undo the checking which ...

commented: helpful explanation and quick replies +1

They are referring to user created controls, not the ones built into .NET. You'd have to derive your own control to do what they are talking about.

As for the above code, you are correct. You need the boolean otherwise when you undo the checking, it causes a CheckChanged event which attempts to undo the checking which causes a CheckChanged event which attempts to undo the checking which ...

Ah. That makes sense then. Hm, bummer, that's more than I was hoping to do right now. Definitely pocketing that one for researching later. I guess it's on to plan B. Thanks for the code and the explanations.

Although it's not on the topic of constructors or transparency, I thought I'd post what I did end up doing to make these controls read only in case anyone is reading this in the future. Basically I just applied an event handler to the "Mouse Down" event of each control, and had it change focus to an unused label on the form. I originally had it on the Enter event, but #1 it wouldn't change there, and #2 MSDN says that changing the focus during that (or several related events) can cause the program to crash. Anywho, it does what I wanted: datepickers, comboboxes and checkboxes now still look like active controls, but they can't be changed.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.