2008-11-01 14 views
5

Volviendo a WinForms en VS2008 después de mucho tiempo ... Cambiando de sitio con un problema OOD en VS2008 Express Edition.¿Cómo puedo hacer que un control de Windows Forms sea de lectura?

Necesito algunos controles para ser widgets de "solo visualización". El usuario no debería poder cambiar el valor de estos controles ... los widgets se actualizan mediante un evento de actualización periódica. Recuerdo vagamente que hay una propiedad ReadOnly que podría establecer para tener este comportamiento ... no puede encontrarlo ahora.

Habilitado propiedad establecida en false: atenúa el contenido de control. Quiero que el control se vea normal. Bloqueado propiedad establecida en falso: parece proteger al usuario de la distorsión accidental del control en el Diseñador de formularios visuales.

¿Qué me estoy perdiendo?

+0

> Quiero que el control se vea normal. Solo me gustaría señalar que es una experiencia UI horrible tener un control de solo lectura que parece lo mismo que un control editable. – FlySwat

+0

Punto observado. Es una aplicación falsa/de prueba para simplemente hacer una demostración de algo ... Creo que UX Gods me dejará vivir :) – Gishu

+0

Pensándolo bien, creo que Images sería la mejor respuesta ... mi forma solo muestra el estado de diferentes válvulas en un real tiempo base Cada widget debe mostrar una imagen diferente basada en un valor de campo de respaldo – Gishu

Respuesta

11

Para algunas winforms típicos controles:

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

Esta es también una buena punta para conservar el aspecto:

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

Aah .. Readonly was for plain textboxes. Los botones de radio también son fáciles. Obtuve un combobox que necesitaría un hack feo ... Por otro lado, si es solo de solo lectura ... podría convertirlo en una etiqueta o en un cuadro de texto. Gracias lo aceptaremos a menos que tengamos un nuevo contendiente. – Gishu

+0

estoy de acuerdo con Jonathan, pero acabo de agregar ese consejo si realmente lo necesita. –

3

Textbox

propiedad .ReadOnly a la verdadera

Controles sin ReadOnly

Otro control no tiene todo el tiempo la propiedad ReadOnly. Tendrá que jugar con los eventos para despegar el proceso de edición y mantener su valor no editable.

1

Dos propiedades relevantes ReadOnly y Enabled. ReadOnly = true evita la edición de grises en el fondo, pero aún permite el enfoque. Enabled = false pone en gris el fondo, el texto y evita la edición o el enfoque.

Las convenciones de la interfaz de usuario de Windows indican al usuario una señal visual de que un control es de solo lectura (de esa forma no intentarán editarlo y se frustrarán posteriormente). El estado inhabilitado en gris es la convención del sistema definida, pero es discutible en demasía (y no lo suficientemente legible).

La ruta más simple es probablemente establecer su control en ReadOnly, establecer el fondo en System.Drawing.SystemColors.Window y luego bloquear los mensajes de enfoque. Puede hacer esto capturando eventos OnEnter e inmediatamente moviendo Focus a otro control que no sea de solo lectura (por ejemplo, un botón Cerrar o Editar). O puede derivar su propio control y comer cualquier mensaje WM_SETFOCUS. Ejemplo a continuación.

Creo que varios conjuntos de control de terceros le brindan opciones adicionales y granularidad.

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

Para hacer que los formularios de control Sólo lectura al instante en un clic hace uso de lo siguiente pedazo de código:

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

Entonces llamaremos a partir de su botón evento Click así:

LockControlValues(this) 

Espero, esto ayuda a resolver su problema:

Happy Programming,

Rajan Arora www.simplyrajan.co.nr

0

Me dieron esta misma exigencia en el trabajo de ayer. Excepto que en lugar de un cuadro de texto tuve que deshabilitar un formulario completo sin cambiar su color.

Así que sustituyen una llamada a

form->Enabled = false; 

con

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

que funcionaba bien. Puede ver arriba que estoy usando C++ administrado. El formulario completo ahora está desactivado, pero no está atenuado.

Cuestiones relacionadas