Genesis Vargas J

Multiplicación de matrices usando Datagridviews y Combox dinámicos en C# (Tutorial/Código fuente)

Comparte:

Hola amigos, bastante tiempo sin publicar pero la verdad es que estoy trabajando en un proyecto mas o menos grande y no había podido sacar una horita para publicar aquí en la página. Esta vez les voy a aportar algo que casi siempre nos ha tocado hacer en la universidad y que es a veces un poco "complicado" de por las validaciones, pero en realidad es sencillo.

Se trata de multiplicar matrices, pero no sólo eso, también de que las matrices se vean representadas en Datagridviews y que sean dinámicas a partir de la selección que escoga el usuario usando Combobox para alterar las filas y columnas de nuestra matriz.

Lo primero será diseñar la interfaz, para esto necesitaremos: 3 Datagridviews (Matriz1, Matriz2, Matriz Resultante), 4 Combobox (fila y columnas de ambas matrices), 1 Button (obvio para calcular), 1 Errorprovider (para mostrar los errores y no tenerlos que mostrar en messagebox) y los labels correpondientes; al final nos quedaría así:

El programa se compone de una clase llamada: "Funciones" y el formulario donde esta la interfaz, el código de nuestra clase sería así:

FUNCIONES.CS

class Funciones
    {
        int i, j, k;

        //funcion par permitir solo números positivos y negativos y la tecla borrar
        public KeyPressEventArgs solo_numeros(DataGridView m, KeyPressEventArgs e)
        {
            //comparo si el caracter es numero, control o negativo y lo habilito
            if (char.IsNumber(e.KeyChar) || char.IsControl(e.KeyChar))
            {
                e.Handled = false;
            }
            else
            {
                e.Handled = true;
            }
            return e;
        }

        //funcion para no permitir teclas
        public KeyPressEventArgs ninguna_tecla(KeyPressEventArgs e)
        {
            //controlo el evento keypresseventargs para todas las teclas
            e.Handled = true;
            return e;
        }

        //metodo para mostrar errores
        public void error(ErrorProvider error, DataGridView m, string mensaje)
        {
            //establezco en el error: primero, el control asociado y segundo el mensaje como tipo string
            error.SetError(m, mensaje);
        }

        //metodo para crear matrices dependeiendo si hay filas y columnas seleccionadas los en datagridviews
        public void crearmatriz(int f, int c, DataGridView m1)
        {
            //verifico si las columnas estan vacias
            if (c != 1 && c != 2 && c != 3 && c != 4 && c != 5 && c != 6 && c != 7 && c != 8 && c != 9 && c != 10)
            {
                //borro las columnas del datagridview
                m1.Columns.Clear();
                for (i = 0; i < 1; i++)
                {
                    // Creo una columna
                    DataGridViewTextBoxColumn col1 = new DataGridViewTextBoxColumn();
                    col1.Width = 30;
                    col1.Name = "columna";
                    col1.MaxInputLength = 2;
                    col1.Resizable = DataGridViewTriState.False;
                    ContextMenuStrip menu = new ContextMenuStrip();
                    col1.ContextMenuStrip = menu;
                    m1.Columns.Add(col1);
                }
                m1.Rows.Add(f);
            }
            else
            {
                //borro las columnas del datagridview
                m1.Columns.Clear();
                for (i = 0; i < c; i++)
                {
                    //creo una columna
                    DataGridViewTextBoxColumn col1 = new DataGridViewTextBoxColumn();
                    col1.Width = 30;
                    col1.Name = "columna";
                    col1.MaxInputLength = 2;
                    col1.Resizable = DataGridViewTriState.False;
                    ContextMenuStrip menu = new ContextMenuStrip();
                    menu.IsAccessible = false;
                    col1.ContextMenuStrip = menu;
                    m1.Columns.Add(col1);
                }
                m1.Rows.Add(f);
            }
        }

        //funcion para ver si hay celdas vacias o hay numeros mal digitados
        /*utilizo el for each porque con el for me queda mas dificil saber si la celda es vacía
        ya que en c# no se puede hacer lo que se me ocurrio primero: if (m[i,j]="")... ademas
           un  for each hace el recorrido de manera completa sin importar el numero de filas o columnas*/
        public bool celdas_vacias(DataGridView m)
        {
            bool vacia;
            vacia = false;
            foreach (DataGridViewRow fila in m.Rows)
            {
                //recorro las celdas de cada fila
                foreach (DataGridViewCell celda in fila.Cells)
                {
                    // declaro un objeto y le asigno el valor de cada celda
                    object valor = celda.Value;
                    //comparo si ese valor es nulo o si el valor es de tipo dbnull
                    if ((valor == null) || (object.ReferenceEquals(valor, DBNull.Value)))
                    {
                        vacia = true;
                    }
                }
            }
            return vacia;
        }
        //funcion para multiplicar matrices

        public DataGridView multiplicacion(int f, int c, int c2, DataGridView m1, DataGridView m2, DataGridView res)
        {
            for (i = 0; i < f; i++)
            {
                for (j = 0; j < c2; j++)
                {
                    res[j, i].Value = 0;
                    for (k = 0; k < c; k++)
                    {
                        res[j, i].Value = Convert.ToInt32(res[j, i].Value) + Convert.ToInt32(m1[k, i].Value) * Convert.ToInt32(m2[j, k].Value);
                    }
                }
            }
            return res;
        }
    }

Bueno, creo que mejor explicado no puede estar, Obviamente deben declarar el using de System.Windows.Forms, ya que estamos trabajando funciones con este namescpace. Ahora sólo falta agregar los eventos en el formulario e instanciar la clase "funciones" para acceder a sus funciones y métodos y el código sería el siguiente:

FRMMULTIPLICACION.CS

public partial class FrmMultiplicacion : Form
    {
        public FrmMultiplicacion()
        {
            InitializeComponent();
        }

        int m, n, m2, n2;

        //instanciamos la clase
        Funciones fun = new Funciones();
         //verificamos si el combobox de la columna es vacio y damos paso a que se cree la matriz con una sola columna sino se crea la matriz con las columnas que se escogieron en el combobox
        void Cmbx_filasSelectedIndexChanged(object sender, EventArgs e)
        {
            if (cmbx_columnas.Text == "")
            {
                m = Convert.ToInt32(cmbx_filas.Text);
                fun.crearmatriz(m, n, dgv_matriz1);
            }
            else
            {
                m = Convert.ToInt32(cmbx_filas.Text);
                n = Convert.ToInt32(cmbx_columnas.Text);
                fun.crearmatriz(m, n, dgv_matriz1);    
            }
        }
         //verificamos si el combobox de las filas no es vacio, si lo es advertimos que primero debe escoger el numero de filas para poder crear la matriz en el datagridview
        void Cmbx_columnasSelectedIndexChanged(object sender, EventArgs e)
        {
            if (cmbx_filas.Text != "")
            {
                m = Convert.ToInt32(cmbx_filas.Text);
                n = Convert.ToInt32(cmbx_columnas.Text);
                fun.crearmatriz(m, n, dgv_matriz1);
                fun.error(error, dgv_matriz1,"");
            }
            else
            {
                fun.error(error, dgv_matriz1,"NO HA ESCOGIDO EL NUMERO DE FILAS DE LA MATRIZ");
            }
        }
        //verificamos si el combobox de la columna es vacio y damos paso a que se cree la matriz con una sola columna sino se crea la matriz con las columnas que se escogieron en el combobox  
        void Cmbx_filas2SelectedIndexChanged(object sender, EventArgs e)
        {
            if (cmbx_columnas2.Text == "")
            {
                m2 = Convert.ToInt32(cmbx_filas2.Text);
                fun.crearmatriz(m2, n2, dgv_matriz2);    
            }
            else
            {
                m2 = Convert.ToInt32(cmbx_filas2.Text);
                n2 = Convert.ToInt32(cmbx_columnas2.Text);
                fun.crearmatriz(m2, n2, dgv_matriz2);    
            }
        }
         //verificamos si el combobox de las filas no es vacio, si lo es advertimos que primero debe escoger el numero de filas para poder crear la matriz en el datagridview        
        void Cmbx_columnas2SelectedIndexChanged(object sender, EventArgs e)
        {
            if (cmbx_filas2.Text != "")
            {
                m2 = Convert.ToInt32(cmbx_filas2.Text);
                n2 = Convert.ToInt32(cmbx_columnas2.Text);
                fun.crearmatriz(m2, n2, dgv_matriz2);
                fun.error(error, dgv_matriz2,"");
            }
            else
            {
                fun.error(error, dgv_matriz2,"NO HA ESCOGIDO EL NUMERO DE FILAS DE LA MATRIZ");
            }
        }
        
        void Btn_calcularClick(object sender, EventArgs e)
        {

            //verificamos que no hayan celdas vacias, que los datagridviews esten creados y que el numero de columnas de la matriz 1 sea igual al numero de filas de la matriz 2 para poder calcular la matriz resultante
            if (dgv_matriz1.Rows.Count != 0 && dgv_matriz2.Rows.Count != 0 && cmbx_columnas.Text == cmbx_filas2.Text && !fun.celdas_vacias(dgv_matriz1) && !fun.celdas_vacias(dgv_matriz2))
            {
                fun.error(error, dgv_matriz1,"");
                fun.crearmatriz(m, n2, dgv_resultado);
                fun.multiplicacion(m, n, n2, dgv_matriz1, dgv_matriz2, dgv_resultado);
            }
            else
            {
                fun.error(error, dgv_matriz1,"LAS COLUMNAS DE LA PRIMERA MATRIZ DEBEN SER IGUALES A LAS FILAS DE LA SEGUNDA MATRIZ, NO SE HAN CONSTRUIDO LAS MATRICES, HAY CELDAS VACIAS, O ESTAS DIGITANDO MAL LOS NUMEROS NEGATIVOS");
            }
        }
         //solo permitimos que tecleen numeros en el datagridview       
        void Dgv_matriz1KeyPress(object sender, KeyPressEventArgs e)
        {
            fun.solo_numeros(dgv_matriz1, e);
        }
         //solo permitimos que tecleen numeros en el datagridview
        void Dgv_matriz2KeyPress(object sender, KeyPressEventArgs e)
        {
            fun.solo_numeros(dgv_matriz2, e);
        }
        //no permitimos ni una tecla para que no alteren la seleccion
        void Cmbx_filasKeyPress(object sender, KeyPressEventArgs e)
        {
            fun.ninguna_tecla(e);
        }
         //no permitimos ni una tecla para que no alteren la seleccion
        void Cmbx_columnasKeyPress(object sender, KeyPressEventArgs e)
        {
            fun.ninguna_tecla(e);
        }
       //no permitimos ni una tecla para que no alteren la seleccion
        void Cmbx_filas2KeyPress(object sender, KeyPressEventArgs e)
        {
            fun.ninguna_tecla(e);
        }
        //no permitimos ni una tecla para que no alteren la seleccion
        void Cmbx_columnas2KeyPress(object sender, KeyPressEventArgs e)
        {
            fun.ninguna_tecla(e);
        }
        //agregamos los eventos keypress del datagridview1 en cada celda en tiempo de ejecucion
        void Dgv_matriz1EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
        {
            TextBox celda = e.Control as TextBox;
            celda.KeyPress -= new KeyPressEventHandler(Dgv_matriz1KeyPress);
            celda.KeyPress += new KeyPressEventHandler(Dgv_matriz1KeyPress);
        }
        //agregamos los eventos keypress del datagridview2 en cada celda en tiempo de ejecucion
        void Dgv_matriz2EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
        {
            TextBox celda = e.Control as TextBox;
            celda.KeyPress -= new KeyPressEventHandler(Dgv_matriz2KeyPress);
            celda.KeyPress += new KeyPressEventHandler(Dgv_matriz2KeyPress);
        }
    }

Bueno eso es todo espero que les sirva mucho para aprender y practicar. Les dejo una carpeta comprimida para que descarguen el ejemplo.

Si te gusto el tutorial no dudes en compartirlo y dejar tu comentario.

Comentarios


genesis vargas

Soy Genesis Vargas Jiménez, autor de éste blog. Me gusta desarrollar software en todas las plataformas (web, móvil y desktop) y compartir conocimiento para ayudar a muchas personas.

Desde el 2015 soy MVP Microsoft en Visual Studio y tecnologías de desarrollo, reconocimiento que me enorgullece mucho.

MVP Genesis Vargas J

A PHP Error was encountered

Severity: Core Warning

Message: Module 'timezonedb' already loaded

Filename: Unknown

Line Number: 0

Backtrace: