views:

69

answers:

5

.Net: Why we can't access to some properties of a control programmatically in winforms? For example, "Locked" property of a groupbox is not accessible via code. So What Possibly can I do when I want to locked it programmatically ? Using Enabled = False will greyed out all controls within it and this is not what I wanna to be.

Any Suggestions ?

+1  A: 

Do you know what Locked really mean? This isn't a normal property and isn't affecting runtime anyhow, only designer. You probably should go to the problem you're trying to solve. I can assure you: the "Locked" property isn't needed for that.

Dmitriy Matveev
Well, I do not know that whether you have developed application with Vb6 or not, but there was a control named frame which we could locked it (and also all its child controls within it) so that user could not start entring data. But the form was clear and not grey.
odiseh
OK, sorry, but I still think you shouldn't do this, because this may break user's expectation on the behavior of your application.
Dmitriy Matveev
A: 

You could disable it!!!!

daveTextBox.Enabled = False

This will obviously change the look of the control. If you don't want to change the look of the control then override the key press event handler to do nothing.

David Relihan
The question is about different thing.
Dmitriy Matveev
I disagree - my understanding of the question is that the problem is programatically locking a control
David Relihan
@David: No.If you just disable it (Enabled = false) it and all its child controls within it will be grayed out. This is not what I really want.
odiseh
@odiseh That's what I said in my reply - that's why I suggested overriding the key press event handler to do nothing
David Relihan
+1  A: 

If you want to disable your controls without greying them out, the exact procedure to do so can be fairly complicated and depends on the control's type. I'm giving you some pointers below for TextBox, for CheckBox & RadioButton, and for ComboBox controls.

Bear in mind the possibility that this capability is not built uniformly into Winforms for a reason: A control that looks enabled, but is in fact disabled (read-only) will possibly confuse many users of your application, because dealing with your controls won't match their expectations of how Windows controls usually behave.

TextBox

Set the TextBox.ReadOnly property to true.
(See e.g. the article Creating a Read-Only Text Box on MSDN.)

CheckBox (and RadioButton)

Set the CheckBox.AutoCheck property to false.
Note that this also works for RadioButton controls.


Edit: Unfortunately, I cannot retrieve my sources for making a ComboBox read-only right now. However, it's fairly complicated and involves intercepting window messages in WndProc. Perhaps take a look at this article on CodeProject instead.

stakx
Don't go altering the *ENABLED* property with unneeded API calls. When a combobox is disabled it's only disabled for the user, not code-behind.Just attach eventhandlers to reset colors on disabled.
riffnl
+1  A: 

Locked is not a property at all - it is just a value stored in the resource file. Locking the Form control yields a boolean resource value $this.Locked set to true.

Further some properties are attached to controls using IExtenderProvider similar to attached properties in WPF. For example the designer will show a propery ToolTip for all controls after adding a ToolTip control to the designer. To set the tool tip text by code you have to use

this.toolTip1.SetToolTip(this.button1, "A button.");

because there is no ToolTip property for controls.

And there are more mechanisms like ICustomTypeDescriptor that cause different properties to be shown in the designer than the properties that are really defined for the control.

There is a generic solution to disable WinForms controls without graying them but unfortunately I can neither remember nor find it...

Daniel Brückner
A: 

As others have already pointed out, what you actually want to do is to make the controls readonly, but except for textboxes and radiobuttons this can be fairly complicated.

Below is an excerpt from some code I've written to handle something like this, but the client wanted cheap rather than perfect so I had some flexibility so it might not work for you. The method is just called by SetControlsReadonly(gb.Controls) (assuming a groupbox called gb).

Private Sub SetControlsReadonly(ByVal ctrls As Windows.Forms.Control.ControlCollection)
  For Each ctrl As Control In ctrls
     ctrl.Enabled = True ' first enable everything so that it'll all look the same
     If TypeOf ctrl Is TextBox Then
        CType(ctrl, TextBox).ReadOnly = True
     ElseIf TypeOf ctrl Is Button Then
        CType(ctrl, Button).Enabled = False
     ElseIf TypeOf ctrl Is CheckBox Then
        CType(ctrl, CheckBox).AutoCheck = False
     ElseIf TypeOf ctrl Is ComboBox Then
        ctrl.Enabled = False 
        if ctrl.Tag IsNot Nothing Then
            ' call method that hides the combo and instead shows a readonly textbox in the same location containing the same data
        End If
     ElseIf TypeOf ctrl Is DateTimePicker Then
        ctrl.Enabled = False
     End If
     SetControlsReadonly(ctrl.Controls)
  Next
End Sub
ho1
You are missing a final `Else` block where you handle all other control types. If you don't include that, and someone puts a control on a form that your method doesn't know how to handle, it won't get disabled. -- IMO it would be better design to derive your own control classes (from the standard controls) that implement a common interface `IHaveReadOnlyProperty` (exposing a `ReadOnly` property). Your method then checks whether a control supports that interface; if so, it sets the exposed `ReadOnly` property to `false`; otherwise, it does the next-best thing, ie. it sets `Enabled` to `false`.
stakx
Well, I'm not going to say that your design wouldn't be better (especially if starting from scratch), but as I said, the client wanted cheap rather than perfect. However, I disagree regarding the `Else`, if you add an `Else` that disables everything else, you have to make sure that you don't have unexpected controls there (For example a tab control, or a groupbox that contains textboxes etc) since otherwise it wouldn't work as expected.
ho1