El Blog de Óscar Sotorrío Sánchez - MCP Application Development Foundation - C#

Todo lo que vaya aprendiendo de .NET, C#, ASP.NET, SQL Server, etc, lo compartiré con vosotros.

El autor:

Óscar Sotorrío Sánchez
Contacto Send mail

Encuéntralo

Álguien dijo...


No sé cómo será la III Guerra Mundíal, pero sí la IV...con piedras y palos.

Albert Einstein

DataGridView: posicionar scroll

Esta es una cuestión muy simple y sencilla pero me ha parecido correcto incluirla en un post porque es de ese tipo de cosas que siempre se preguntan y nadie escribe sobre ello porque parece demasiado trivial.

Supongamos el caso de un DataGridView que contiene multitud de líneas y el usuario se desplaza por el mismo con un scroll vertical. En un momento dado el usuario cambia el contenido de una celda y actualiza para que los cambios sean volcados en la base de datos que alimenta el DataGridView.

¿Qué ocurre?. Que al actualizar el scroll sube a la parte de arriba, perdiendo de vista en la pantalla el cambio efectuado.

La solución es la siguiente:

            int indiceFilaSelec dataGridView1.CurrentRow.Index;
            
dataGridView1.FirstDisplayedScrollingRowIndex indiceFilaSelec;

También se puede obtener el índice de la fila seleccionada con dataGridView1.SelectedRows[0].Index;


Posted by Oscar.SS on jueves, 02 de julio de 2009 8:51
Permalink | Comentarios (0) | Post RSSRSS comment feed

Acceder a los controles de otro formulario.

En ocasiones es necesario acceder a los controles de un formulario desde otro formulario distinto. Por ejemplo, puede darse el caso de dos formularios, "padre e hijo", y que necesitemos escribir un mensaje en un TexBox del formulario "padre" cuando se realiza una determinada acción (evento) desde el formulario "hijo".

En primer lugar debemos crear una instancia del formulario al que queremos acceder. Esta instancia será creada en el lugar que queremos tener el acceso.

Form1 formularioPadre = new Form1();

Luego debes acceder al control deseado por medio de la colección Controls del objeto creado, por ejemplo:

((TextBox)formularioPadre.Controls["nombreDelControl"]).Text = “Texto en un TextBox de otro formulario”;

Como se puede obserbar, es necesaria una conversión (catch) del valor devuelto por la colección Controls al tipo de control adecuado.

La colección Controls esta “indexada”, esto quiere decir que sí lo prefieres puedes acceder a sus elementos por medio de un índice de tipo int (Int32), en lugar de utilizar el nombre del control. Esto es muy apropiado cuando quieres acceder a todos los elementos (controles) en un bucle for() o en una colección propia que guarde objetos de tipo Control.

Es un "truco" muy sencillo pero espero os sirva a más de uno.

 

Nota: Para ayudar a un compañero de los foros MSDN he decidido dejar para descarga un pequeño ejemplo de esta técnica. Se trata tan solo de un ejemplo, de como acceder a las propiedades y métodos de los controles que están situados en otro formulario. Digo esto porque se ha simplificado al máximo, dejando de lado algunas comprobaciones, y resaltando lo que de verdad importa en este caso. 

AccesoControlesForm.zip (44,22 kb)

Solo espero que ahora quede más claro este asunto. Para cualquier problema...aquí estamos Wink



Categories: Desarrollo Windows
Posted by Oscar.SS on domingo, 19 de octubre de 2008 12:11
Permalink | Comentarios (5) | Post RSSRSS comment feed

El método OnPaint() y gráficos en un formulario.

Hace unas semanas hablábamos sobre la persistencia de gráficos en los controles de un formulario. Ahora vamos a comentar como dibujar sobre un formulario.

En este caso, para que los gráficos persistan, no es necesario crear un mapa de bits, aunque también es posible hacerlo. Bastará con que implementemos todas las instrucciones de dibujo en el evento Paint() de nuestro formulario (o de nuestros controles). Así de fácil.

Dado que dibujar utilizando el evento Paint() no necesita muchas explicaciones, vamos a ver otra técnica basada en dibujar con el método virtual OnPaint().

¿Dónde está definido el método OnPaint()?. El método virtual OnPaint() pertenece a la clase Control del espacio de nombres System.Windows.Forms.

¿Cómo está definido el método OnPaint()?. Como ya he comentado antes es un método virtual. Esto quiere decir que puede ser redefinido (override) en las clases derivadas de la clase base. Estos conceptos son de POO y por lo tanto, profundizaremos en ellos en otro artículo.

¿Qué hace el método OnPaint()?. Simplemente provoca el evento Paint() del formulario.

¿Por qué utilizar el método OnPaint()?. Como se puede ver en la definición MSDN del método OnPaint(), este contiene un parámetro “e” del tipo PaintEventArgs que proporciona datos de eventos. Más concretamente, proporciona la propiedad Graphics y la propiedad ClipRectangle sobre la que se va a dibujar. Es decir, que con el parámetro “e” tenemos toda la información necesaria para poder dibujar directamente.

Solo queda aclarar que al redefinir este método, Visual Studio genera automáticamente una llamada al método OnPaint() de la clase base. Es decir;

base.OnPaint(e);

Esto es necesario para evitar problemas por ejemplo con los estilos virtuales de los sistemas operativos.

¡Pasemos a la acción!. Abramos el editor de Visual Studio y dibujemos sobre el formulario un triangulo que será rellenado por un color especificado.

Aquí os dejo el código de esta sencilla aplicación que no merece más que algunos comentarios. Como siempre al final veremos una imagen con el resultado de ejecutar nuestra aplicación.

 

namespace Gráficos_OnPaint
{
    
public partial class Form1 : Form
    {
        
public Form1()
        {
            InitializeComponent()
;
        
}
        
protected override void OnPaint(PaintEventArgs e)
        {
            
//Llamada al método de la clase base.
            
base.OnPaint(e);

            
//Establecemos los vértices de un triángulo.
            
Point Vertice1 = new Point(50200);
            
Point Vertice2 = new Point(250200);
            
Point Vertice3 = new Point(15050);

            
//Cargamos en memoria (instanciar) un objeto GraphicsPath. 
            
GraphicsPath ruta = new GraphicsPath();

            
//Establecemos una secuencia de lineas sobre el objeto "ruta".
            
ruta.AddLine(Vertice1, Vertice2);
            
ruta.AddLine(Vertice2, Vertice3);
            
ruta.AddLine(Vertice3, Vertice1);

            
//Dibujamos la secuencia de lineas.
            
e.Graphics.DrawPath(new Pen(Color.Black, 4), ruta);

            
//Rellenamos con un color el interior de la secuencia de lineas.
            
e.Graphics.FillPath(new SolidBrush(Color.Orange), ruta);
        
}
    }
}



Categories: Desarrollo Windows
Posted by Oscar.SS on lunes, 31 de marzo de 2008 4:07
Permalink | Comentarios (0) | Post RSSRSS comment feed

Manejar valores de configuración.

¿Qué son los valores de configuración?. Supongamos una aplicación de tipo Windows (Windows Applications) donde el usuario tiene la opción de establecer el tamaño de la ventana de nuestra aplicación. Bien, puede interesar que la próxima vez que se ejecute la aplicación, esta,” recuerde” el tamaño de la ventana que estableció el usuario la última vez. Incluso puede interesar que la “recuerde” para un usuario en concreto.

Esto son los valores de configuración. Todas aquellas propiedades de nuestra aplicación (formularios y controles) que deseemos queden registradas para la próxima ejecución del programa.

Los valores de configuración se dividen en dos niveles:

1- Valores de configuración a nivel usuario. Son de lectura y escritura. Pueden ser establecidos para un usuario en concreto.

2- Valores de configuración a nivel aplicación. Solamente son de lectura. Y son comunes a todos los usuarios de la aplicación.

¿Donde se guardan los valores de configuración?. Quedan registrados en un archivo de nuestro proyecto cuyo nombre es Settings.Designer.cs. Lo cierto es que este archivo pertenece al espacio de nombres “nombre_proyecto.Properties”. Para registrar los valores de configuración utilizaremos el método Save() de la clase Settings que pertenece a este espacio de nombres.

Para ser más exactos podemos decir que la definición de las propiedades de configuración se encuentra en el fichero nombre_proyecto.exe.config, el cual está ubicado en el directorio bin\Debug. Este fichero es de formato XML.

Lo mejor es que pasemos a la acción. Antes de empezar, decir que como siempre, existen diferentes técnicas para hacer lo mismo. Aquí veremos, bajo mi modesta opinión, la que considero más sencilla, clara y funcional.

Comencemos. Esta es una de esas cosas que son fáciles de hacer pero difíciles de explicar. ¡Haber que tal lo hago!.

Descripción del procedimiento general:

1- Definir las propiedades de configuración por medio del IDE de Visual Studio.

2- En el evento Load de nuestro formulario establecemos las propiedades de los controles (o del formulario) asignándole el valor guardado en las “propiedades de configuración”. Ejemplo:

textBox1.BackColor = Properties.Settings.Default.configuracion_color;

3- En el evento FormClosing del formulario guardamos los valores de las propiedades de los controles (o del formulario) en las propiedades de configuración. Seguidamente guardamos estos valores. Ejemplo:

Properties.Settings.Default.configuracion_color = textBox1.BackColor;

Properties.Settings.Default.Save();

En el paso 2 del procedimiento anterior lo que se pretende es que cuando la aplicación se inicie, todas las propiedades de los controles recuperen los valores que están guardos.

En cambio, en el paso 3, lo que se pretende es que todos los cambios que hagamos en nuestra aplicación durante la ejecución del mismo, se guarden en las propiedades de configuración. Evidentemente este paso no tendremos que tenerlo en cuenta cuando trabajemos con valores de configuración a nivel de aplicación. Como se comento antes, estos valores son de solo lectura y por lo tanto no podremos cambiarlos durante la ejecución del programa.

Ahora sí que empezamos…jeje.

Abrimos el editor de Visual Studio con una aplicación Windows (Windows Applications) y creamos una interfaz parecida a esta:

 

 

 

 

Nota: La propiedad PasswordChar del textBox contraseña tiene establecido su valor en “#”.

Una vez creada la interfaz pasamos a definir las propiedades de configuración. Para ello debemos abrir la ventana Propiedades de nuestro proyecto. Hacemos click con el botón secundario del ratón sobre el nombre de nuestro proyecto en el explorador de soluciones. En el menú contextual que aparece elegimos Propiedades.

 



Aunque la forma más rápida de abrir la ventana Propiedades es haciendo doble click sobre el fichero Properties de nuestro proyecto. En la ventana Propiedades elegimos la ficha Configuración. Este es aspecto que tiene esta ficha (ventana):

 

 

 

Expliquemos que cometido tiene cada uno de los campos de esta ventana.

Nombre: es el nombre que tiene nuestra propiedad de configuración. Con este nombre accederemos al valor que contenga por medio del código.

Tipo: tipo de datos que contiene nuestra propiedad de configuración.

Ámbito: Se ha comentado antes. Ámbito de usuario o ámbito de aplicación.

Valor: Valor predeterminado para esta propiedad de configuración (valor de configuración) en concreto.

Rellenamos los campos como se muestra en la siguiente imagen:

 

 

Expliquemos que cometido tiene, para nuestra aplicación en concreto, cada una de las propiedades de configuración que acabamos de definir.

VConfig_Usuario: almacena el nombre del usuario introducido por pantalla.

VConfig_Contraseña: almacena la contraseña del usuario.

VConfig_Recordar: almacena el estado del CheckBox. Si esta seleccionado o no.

Localización_Form: almacena la posición inicial de la ventana cuando se carga, dado que es un valor de configuración a nivel de aplicación, será siempre el mismo valor (450;250) y no podremos cambiarlo.

Tan solo queda escribir el código de nuestra aplicación siguiendo las pautas del procedimiento general descrito anteriormente.

 

namespace Valores_Config
{
    
public partial class Form1 : Form
    {
        
//Defenimos una constante que tiene el mismo valor que el la Propiedad De
        //Configuración VConfig_Recordar establecido en la ficha Configuración de
        //propiedades del proyecto.

        
const bool CheckBox_Inicial = false;

        public 
Form1()
        {
            InitializeComponent()
;
        
}

        
private void Form1_Load(object sender, EventArgs e)
        {
            
//Cuando carga el formulario esteblecemos las propiedades de los controles
            //con los valores guardados en las Propiedades De Configuración.

            
textBox1.Text Properties.Settings.Default.VConfig_Usuario;
            
textBox2.Text Properties.Settings.Default.VConfig_Contraseña;

            
checkBox1.Checked Properties.Settings.Default.VConfig_Recordar;

            this
.Location Properties.Settings.Default.Localizacion_Form;
        
}

        
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            
//Cuando se cierra el formulario comprobamos si el CheckBox esta
            //seleccionado, en ese caso, guardamos las propiedades de los controles
            //TextBox en los Valores De Configuración.

            
if (checkBox1.Checked == true)
            {
                Properties.Settings.Default.VConfig_Usuario 
textBox1.Text;
                
Properties.Settings.Default.VConfig_Contraseña textBox2.Text;
            
}
            
else
            
{
                Properties.Settings.Default.VConfig_Usuario 
= string.Empty;
                
Properties.Settings.Default.VConfig_Contraseña = string.Empty;
            
}

            
//Asignamos el estado del CheckBox en los Valores De Configuración.
            
Properties.Settings.Default.VConfig_Recordar checkBox1.Checked;

            
//Salvamos, almacenamos o guardamos todos los Valores De Configuración.
            
Properties.Settings.Default.Save();
        
}

        
private void Aceptar_Click(object sender, EventArgs e)
        {
            
this.Close();
        
}

        
private void Cancelar_Click(object sender, EventArgs e)
        {
            checkBox1.Checked 
CheckBox_Inicial;
            this
.Close();
        
}

    }
}

 

Para ver los efectos de los valores de configuración podemos ejecutar (F5) nuestra aplicación y mover la ventana de sitio. Cerramos la aplicación y volvemos ejecutarla para comprobar que la ventana siempre aparece en el mismo sitio.

También podemos escribir en los textBox y elegir “Recordar en este equipo”. Pulsamos “Aceptar”. Volvemos a ejecutar la aplicación para comprobar que se han guardado y recuperado todos los cambios efectuados.

 


Categories: Desarrollo Windows
Posted by Oscar.SS on domingo, 23 de marzo de 2008 2:58
Permalink | Comentarios (0) | Post RSSRSS comment feed

El objeto Bipmap y la persistencia de gráficos.

Está claro que dibujar con .NET es fácil. El problema, como siempre reside en las infinitas clases que disponemos en .NET. ¡Aprender lleva mucho tiempo en .NET!.

Cuando se comienza a dibujar suele resultar complicado el tema de la persistencia de gráficos. ¿Que es esto de la "persistencia de gráficos"?.

Supongamos que tenemos una ventana (formulario) abierta en la pantalla. Supongamos también que minimizamos la ventana y a continuación la volvemos a maximizar. ¿Que a ocurrido?.

En realidad la ventana vuelve a redibujarse por completo. Es decir, todos los gráficos y controles que tenga esta ventana, además de la propia ventana, vuelven a dibujarse. Esto es posible porque toda la información de la ventana está cargada en memoria.

Con lo cual, cuando realizamos gráficos en .NET los debemos cargar en memoria para que vuelvan a dibujarse si el formulario se minimiza o es cubierto por otro formulario en pantalla. La forma de hacer esto es por medio de la clase Bitmap del espacio de nombres System.Drawing.

También es posible hacerlo por medio del evento Paint de la clase Control. E incluso "más elegante", sobrescribiendo el método OnPaint(). Pero todo esto...queda para otro artículo.

De momento creemos un proyecto de tipo "Aplicación de Windows Form". En el formulario, agregamos un botón. Desde el IDE establecemos las siguientes propiedades del objeto button1:

-BackColor: GradientActiveCaption
-Location: 20 ; 20
-Size: 240 ; 240
-Text: Pulsar aquí para didujar

Hacemos doble click sobre el botón para acceder a su controlador de evento. A continuación, dentro del método button1_click escribimos el código que realizará el dibujo sobre el propio botón. Para poder dibujar hay que agregar una directiva using al espacio de nombres System.Drawing que es donde se encuentran los objetos de dibujo más usuales.


//Pasos a seguir para la PERSISTENCIA DE GRÁFICOS.

namespace Persitencia_de_Gráficos
{
    
public partial class Form1 : Form
    {
        
public Form1()
        {
            InitializeComponent()
;
        
}

        
private void button1_Click(object sender, EventArgs e)
        {
            
//1- Cargamos un mapa de bits en la memoria del mismo tamaño que el control.
            
Bitmap miMapa = new Bitmap(this.button1.Width, this.button1.Height);

            
//2- El mapa de bits se lo asignamos a la propiedad Image del control
            //(BackgroupImage para Form) sobre el se mostrará la imagen. Es decir,
            //indicamos cual es la imágen que debe mostrar el control.
            
button1.Image miMapa;

            
//3- Creamos la superficie de dibujo. Es decir, le indicamos a un objeto
            //Graphics (miDibujo) donde tiene que dibujar, que dibuje sobre el mapa bits.
            
Graphics miDibujo Graphics.FromImage(miMapa);

            
//4- Dibujamos con el objeto miDibujo

            //Creamos una estructura de puntos. Representan las esquinas de un rectangulo.
            
PuntosDeEsquinas Esquina = new PuntosDeEsquinas();

            
Esquina.superiorX = this.button1.Location.X + 10;
            
Esquina.superiorY = this.button1.Location.Y + 10;
            
Esquina.inferiorX = this.button1.Width - (* (10 20));
            
Esquina.inferiorY = this.button1.Height - (* (10 20));

            
//Creamos un rectangulo con las dimensiones establecidas por las esquinas.
            
Rectangle unRectangulo = new Rectangle(Esquina.superiorX, Esquina.superiorY,
              Esquina.inferiorX, Esquina.inferiorY)
;

            
//Dibujamos un círculo delimitado por el rentengulo (unRectangulo);
            
miDibujo.DrawEllipse(new Pen(Color.BlueViolet, 10), unRectangulo);
        
}

        
struct PuntosDeEsquinas
        {
            
public int superiorX,
              superiorY,
              inferiorX,
              inferiorY
;
        
}
    }
}


Esta es la representación mostrada al ejecutar nuestra aplicación.

Para comprobar la persistencia de los gráficos dibujados solo tenemos que minimizar el formulario, o cubrirlo con otra ventana. Cuando volvamos a mostrar nuestro gráfico comprobaremos felizmente que todo está correctamente dibujado.


Posted by Oscar.SS on sábado, 15 de marzo de 2008 2:25
Permalink | Comentarios (0) | Post RSSRSS comment feed