2008-11-01 8 views
5

Retour à WinForms dans VS2008 après un long moment .. Bricoler avec un problème OOD dans VS2008 Express Edition.Comment faire un contrôle Windows Forms en lecture seule?

J'ai besoin de certains contrôles pour être des widgets "d'affichage seulement". L'utilisateur ne devrait pas être en mesure de changer la valeur de ces contrôles ... les widgets sont mis à jour par un événement tick de mise à jour périodique. Je me souviens vaguement qu'il y avait une propriété ReadOnly que vous pouviez définir pour avoir ce comportement ... Je ne peux pas le trouver maintenant.

La propriété activée est définie sur false: grise le contenu du contrôle. Je veux que le contrôle semble normal. La propriété verrouillée a la valeur false: semble protéger l'utilisateur contre la déformation accidentelle du contrôle dans Visual Designer.

Qu'est-ce qui me manque?

+0

> Je souhaite que le contrôle semble normal. Je voudrais juste souligner que c'est une horrible expérience de l'interface utilisateur d'avoir un contrôle en lecture seule qui ressemble à un contrôle éditable. – FlySwat

+0

Point noté. C'est une fausse application/test pour juste démo quelque chose .. Je pense que les dieux UX me laisseront vivre :) – Gishu

+0

Sur des réflexions, je pense que les images seraient la meilleure réponse .. ma forme montre juste l'état des différentes valves sur un réel base de temps. Chaque widget doit montrer une image différente basée sur une valeur de champ de support – Gishu

Répondre

11

Pour certains contrôles WinForms typiques:

http://jquiz.wordpress.com/2007/05/29/c-winforms-readonly-controls/

Ceci est aussi une bonne astuce pour préserver l'apparence:

Color clr = textBox1.BackColor; 
    textBox1.ReadOnly = true; 
    textBox1.BackColor = clr; 
+0

Aah .. Readonly était pour les zones de texte simples. Les radiobuttons sont faciles aussi. J'ai un combobox qui aurait besoin d'un hack laid .. D'un autre coté si c'est seulement readonly .. Je pourrais aussi bien le transformer en une étiquette ou un textbox. Merci acceptera celui-ci, sauf si nous avons un nouveau concurrent. – Gishu

+0

Je suis d'accord avec Jonathan mais je viens d'ajouter ce conseil si vous en avez vraiment besoin. –

3

Textbox

propriété .ReadOnly true

Commandes sans ReadOnly

Les autres contrôles n'ont pas toujours la propriété ReadOnly. Vous aurez besoin de jouer avec les événements pour enlever le processus d'édition et garder votre valeur non modifiable.

1

Deux propriétés pertinentes ReadOnly et Enabled. ReadOnly = true empêche l'édition de griser l'arrière-plan, mais permet toujours la mise au point. Enabled = false grise l'arrière-plan, le texte et empêche l'édition ou la mise au point.

Les conventions de l'interface utilisateur de Windows indiquent à l'utilisateur qu'un contrôle est en lecture seule (de cette façon, il ne tentera pas de le modifier et sera ensuite frustré). L'état désactivé grisé est la convention de système définie, mais il est discutable trop d'une cue (et pas un legibile assez).

L'itinéraire le plus simple est probababy pour définir votre contrôle sur ReadOnly, définir l'arrière-plan sur System.Drawing.SystemColors.Window, puis bloquer les messages de mise au point. Vous pouvez le faire en attrapant des événements OnEnter et en déplaçant immédiatement Focus vers un autre contrôle qui n'est pas en lecture seule (par exemple, un bouton Fermer ou Modifier). Ou vous pouvez dériver votre propre contrôle et manger tous les messages WM_SETFOCUS. Exemple ci-dessous

Je crois que divers ensembles de contrôles tiers vous offrent des options et une granularité supplémentaires.

public class ReadOnlyTextBox : TextBox 
{ 
    const uint WM_SETFOCUS = 0x0007; 

    public ReadOnlyTextBox() 
    { 
     this.ReadOnly = true; 
     this.BackColor = System.Drawing.SystemColors.Window; 
     this.ForeColor = System.Drawing.SystemColors.WindowText; 
    } 

    protected override void WndProc(ref Message m) 
    { 
     // eat all setfocus messages, pass rest to base 
     if (m.Msg != WM_SETFOCUS) 
     base.WndProc(ref m); 
    } 
} 
4

Pour rendre les formes de contrôle Readonly instantanément sur un seul clic ne pas utiliser le peice suivant du Code:

public void LockControlValues(System.Windows.Forms.Control Container) 
    { 
     try 
     { 
      foreach (Control ctrl in Container.Controls) 
      { 
       if (ctrl.GetType() == typeof(TextBox)) 
        ((TextBox)ctrl).ReadOnly = true; 
       if (ctrl.GetType() == typeof(ComboBox)) 
        ((ComboBox)ctrl).Enabled= false; 
       if (ctrl.GetType() == typeof(CheckBox)) 
        ((CheckBox)ctrl).Enabled = false; 

       if (ctrl.GetType() == typeof(DateTimePicker)) 
        ((DateTimePicker)ctrl).Enabled = false; 

       if (ctrl.Controls.Count > 0) 
        LockControlValues(ctrl); 
      } 
     } 
     catch (Exception ex) 
     { 
      MessageBox.Show(ex.ToString()); 
     } 
    } 

appeler ensuite de votre CLICK événement comme celui-ci:

LockControlValues(this) 

Hope, cela aide à résoudre votre problème:

Happy Programming,

Rajan Arora www.simplyrajan.co.nr

0

m'a donné cette même exigence au travail hier. Sauf qu'au lieu d'une zone de texte, je devais rendre un formulaire entier désactivé sans changer sa couleur.

Je remplacé un appel à

form->Enabled = false; 

avec

IntPtr hWnd = form->Handle; 
HWND window_handle = (HWND)hWnd.ToPointer(); 
::EnableWindow(window_handle, aEnable ? TRUE:FALSE); 

Ce qui a bien fonctionné. Vous pouvez voir ci-dessus que j'utilise C++ géré. Le formulaire entier est maintenant désactivé, mais pas grisé.

Questions connexes