"Si usa algún código del siguiente tutorial, den el icono de ME GUSTA del Facebook que se encuentra en su mano derecha, para que se vuelva Seguidor del Blog y también comentenos que tal les pareció el tutorial"
1. Entorno
- SQL Server 2008
- Visual Studio 2008
2. Introducción
En el tutorial en la Parte II y en la Parte III hemos creado la capa de datos y la capa de negocios respectivamente de nuestra aplicación, ahora solo nos falta crear nuestra capa de presentacion. La capa de presentacion puede ser una aplicacion del tipo escritorio, web, etc. Es por eso que se utiliza la programacion en capas, debido a que no importa que cambiamos hagamos en alguna capa no se sentira en las otras de manera brusca.
3. Desarrollo
3.1. Creando el Proyecto
Ahora debemos de agregar a nuestro proyecto un proyecto del tipo biblioteca de clases que se llamara "CapaPresentacion". No olvidar que debemos de ir a "Archivo-->Agregar-->Nuevo Proyecto"
3.2. Agregando la referencia con la Capa de Negocios
Debemos de establecer la comunicacion entre la Capa de Presentación y la Capa de Negocios. Para eso hacemos clic derecho en nuestro proyecto que se llama "CapaPresentacion" y nos vamos a la opcion de "Agregar Referencia"
Y de ahí seleccionamos que se comunica con la Capa de Negocios
3.3. Formulario frmMantenimientoProducto
En este formulario vamos a realizar un mantenimiento a la tabla Producto de nuestra Base de Datos que se llama BDTutorial y que esta diseñada en SQL Server 2008. A mantenimiento me refiero a los procesos de inserción, actualización y consulta de datos de la tabla Producto. Debemos de diseñar el siguiente formulario
En el cual el componente dgvProducto tiene los siguientes valores de propiedades:
- AllowUserToAddRows = False
- AllowUserToDeleteRows = False
- MultiSelect = False
- ReadOnly = True
- SelectionMode = FullRowSelect
Y como columnas tiene
- codigoProducto
- DataPropertyName = codigoProducto
- HeaderText = codigoProducto
- Visible = False
- Nombre
- DataPropertyName = nombre
- HeaderText = Nombre
- Visible = True
- Precio
- DataPropertyName = precio
- HeaderText = Precio
- Visible = True
En la otra pestaña del tabControl tenemos los siguientes componentes:
Y su código fuente del formulario seria
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; //Comunicarse con la Capa de Negocios using CapaNegocios; //Desarollado por Henry Joe Wong Urquiza namespace CapaPresentacion { public partial class frmMantenimientoProducto : Form { //Variable que nos indica si vamos a insertar un nuevo producto private bool nuevo = false; //Variable que nos indica si vamos a modificar un producto private bool modificar = false; //Constructor del formulario public frmMantenimientoProducto() { InitializeComponent(); } //Evento que se lanza cuando se va a mostrar el formulario private void frmMantenimientoProducto_Load(object sender, EventArgs e) { //Para ubicar al formulario en la parte superior del contenedor this.Top = 0; this.Left = 0; //Le decimos al DataGridView que no auto genere las columnas this.dgvProductos.AutoGenerateColumns = false; //Llenamos el DataGridView con la informacion de todos nuestros //productos this.dgvProductos.DataSource = NegProducto.ObtenerProducto(); //Deshabilita los controles this.habilitar(false); //Establece los botones this.botones(); } //Para mostrar mensaje de confirmacion private void mOK(string men) { MessageBox.Show(men, "MENSAJE", MessageBoxButtons.OK, MessageBoxIcon.Information); } //Para mostrar mensaje de error private void mError(string men) { MessageBox.Show(men, "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error); } //Limpia los controles del formulario private void limpiar() { this.txtNombre.Text = string.Empty; this.nudPrecio.Value = 0; } //Habilita los controles de los formularios private void habilitar(bool valor) { this.txtNombre.ReadOnly = !valor; this.nudPrecio.Enabled = valor; } //Habilita los botones private void botones() { if (this.nuevo || this.modificar) { this.habilitar(true); this.btnNuevo.Enabled = false; this.btnGuardar.Enabled = true; this.btnModificar.Enabled = false; this.btnCancelar.Enabled = true; } else { this.habilitar(false); this.btnNuevo.Enabled = true; this.btnGuardar.Enabled = false; this.btnModificar.Enabled = true; this.btnCancelar.Enabled = false; } } //Evento clic del boton btnNuevo private void btnNuevo_Click(object sender, EventArgs e) { this.nuevo=true; this.modificar=false; this.botones(); this.limpiar(); this.txtCodigo.Text = string.Empty; this.txtNombre.Focus(); } //Evento clic del boton btnGuardar private void btnGuardar_Click(object sender, EventArgs e) { //La variable que almacena si se inserto o se modifico la tabla string rpta = ""; if(this.nuevo) { //Vamos a insertar un producto rpta=NegProducto.Insertar(this.txtNombre.Text.Trim().ToUpper(), this.nudPrecio.Value); }else { //Vamos a modificar un producto rpta=NegProducto.Actualizar(Convert.ToInt32(this.txtCodigo.Text), this.txtNombre.Text.Trim().ToUpper(), this.nudPrecio.Value); } //Si la respuesta fue OK, fue porque se modifico o inserto el Producto //de forma correcta if (rpta.Equals("OK")) { if (this.nuevo) { this.mOK("Se inserto de forma correcta al Producto"); } else { this.mOK("Se actualizo de forma correcta al Producto"); } } else { //Mostramos el mensaje de error this.mError(rpta); } this.nuevo=false; this.modificar=false; this.botones(); this.limpiar(); this.dgvProductos.DataSource = NegProducto.ObtenerProducto(); this.txtCodigo.Text=""; } //Evento clic del boton btnModificar private void btnModificar_Click(object sender, EventArgs e) { //Si no ha seleccionado un producto no puede modificar if(!this.txtCodigo.Text.Equals("")) { this.modificar=true; this.botones(); } else { this.mError("Debe de buscar un producto para Modificar"); } } //Evento clic del boton btnCancelar private void btnCancelar_Click(object sender, EventArgs e) { this.nuevo=false; this.modificar=false; this.botones(); this.limpiar(); this.txtCodigo.Text=string.Empty; } //Evento double clic del DataGridView de Productos private void dgvProductos_DoubleClick(object sender, EventArgs e) { this.txtCodigo.Text = Convert.ToString(this.dgvProductos.CurrentRow.Cells["codigoProducto"].Value); this.txtNombre.Text = Convert.ToString(this.dgvProductos.CurrentRow.Cells["nombre"].Value); this.nudPrecio.Value = Convert.ToDecimal(this.dgvProductos.CurrentRow.Cells["precio"].Value); this.tabControl.SelectedIndex = 1; } } }
3.4. Formulario frmSeleccionarProducto
Es un formulario del tipo modal que nos permitirá seleccionar un producto de nuestra base de datos para registrar la venta. Y tiene el siguiente diseño
En el cual el componente dgvProducto tiene los siguientes valores de propiedades:
- AllowUserToAddRows = False
- AllowUserToDeleteRows = False
- MultiSelect = False
- ReadOnly = True
- SelectionMode = FullRowSelect
Y como columnas tiene
- codigoProducto
- DataPropertyName = codigoProducto
- HeaderText = codigoProducto
- Visible = False
- Nombre
- DataPropertyName = nombre
- HeaderText = Nombre
- Visible = True
- Precio
- DataPropertyName = precio
- HeaderText = Precio
- Visible = True
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; //Comunicarse con la Capa de Negocios using CapaNegocios; //Desarollado por Henry Joe Wong Urquiza namespace CapaPresentacion { public partial class frmSeleccionarProducto : Form { //El formulario padre private frmRegistrarVenta frame; //El constructor del formulario public frmSeleccionarProducto() { InitializeComponent(); } //Establece los valores del formulario padre public void estableceFormulario(frmRegistrarVenta frame) { this.frame = frame; } //Evento que se ejecuta cuando se muestra el formulario private void frmSeleccionarProducto_Load(object sender, EventArgs e) { //Que no se genere las columnas de forma automatica this.dgvProducto.AutoGenerateColumns = false; //Obtiene todos los productos y lo asigana al DataGridView this.dgvProducto.DataSource = NegProducto.ObtenerProducto(); } //Evento double clic del DataGridView private void dgvProducto_DoubleClick(object sender, EventArgs e) { //Estableciendo los datos a las cajas de texto del formulario padre this.frame.codigoProductoSeleccionado = Convert.ToInt32(this.dgvProducto.CurrentRow.Cells["codigoProducto"].Value); this.frame.txtProducto.Text = Convert.ToString(this.dgvProducto.CurrentRow.Cells["nombre"].Value); this.frame.txtPrecio.Text = Convert.ToString(this.dgvProducto.CurrentRow.Cells["precio"].Value); //Cerrando el formulario this.Hide(); } } }
3.5. Formulario frmRegistrarVenta
Este formulario es la parte principal del sistema en cual se registra la venta. Tener en cuenta que si el detalle de la venta es mayor a 50 soles, dolares, euros, etc se le aplica un descuento del 5% del sub total de la venta. Debemos realizar el siguiente diseño del formulario
En cual la accesibilidad de los controles txtProducto y txtPrecio es del tipo Internal y tiene la propiedad ReadOnly en True.
Y ademas el componente dgvDetalle tiene los siguientes valores de propiedades:
- AllowUserToAddRows = False
- AllowUserToDeleteRows = False
- MultiSelect = False
- ReadOnly = True
- SelectionMode = FullRowSelect
Y como columnas tiene
- codigoProducto
- DataPropertyName = codigoProducto
- HeaderText = codigoProducto
- Visible = False
- Producto
- DataPropertyName = Producto
- HeaderText = Producto
- Visible = True
- Cantidad
- DataPropertyName = cantidad
- HeaderText = Cantidad
- Visible = True
- PU
- DataPropertyName = PU
- HeaderText = PU
- Visible = True
- Descuento
- DataPropertyName = Descuento
- HeaderText = Descuento
- Visible = True
- SubTotal
- DataPropertyName = subTotal
- HeaderText = SubTotal
- Visible = True
Y como código fuente tiene lo siguiente:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; //Comunicarse con la Capa de Negocios using CapaNegocios; //Desarollado por Henry Joe Wong Urquiza namespace CapaPresentacion { public partial class frmRegistrarVenta : Form { //DataTable que se encargara de guardar el detalle de la venta //de forma temporal private DataTable dtDetalle; //Codigo del producto seleccionado internal int codigoProductoSeleccionado = -1; //Variable que almacena el total de la venta private decimal totalPagar = 0; //El constructor de la clase public frmRegistrarVenta() { InitializeComponent(); } //Metodo que se ejecuta al cargar el formulario private void frmRegistrarVenta_Load(object sender, EventArgs e) { this.Top = 0; this.Left = 0; this.crearTabla(); this.WindowState = FormWindowState.Maximized; } //Limpia todos los controles del formulario private void limpiarControles() { this.txtCliente.Text = string.Empty; this.codigoProductoSeleccionado = -1; this.txtProducto.Text = string.Empty; this.txtPrecio.Text = string.Empty; this.nudCantidad.Value = 1; this.crearTabla(); this.lblTotalPagar.Text = "Total Pagar: S/. 0.00"; } //Crea la tabla de Detalle private void crearTabla() { //Crea la tabla con el nombre de Detalle this.dtDetalle = new DataTable("Detalle"); //Agrega las columnas que tendra la tabla this.dtDetalle.Columns.Add("codigoProducto", System.Type.GetType("System.Int32")); this.dtDetalle.Columns.Add("Producto", System.Type.GetType("System.String")); this.dtDetalle.Columns.Add("cantidad", System.Type.GetType("System.Decimal")); this.dtDetalle.Columns.Add("PU", System.Type.GetType("System.Decimal")); this.dtDetalle.Columns.Add("Descuento", System.Type.GetType("System.Decimal")); this.dtDetalle.Columns.Add("subTotal", System.Type.GetType("System.Decimal")); //Relacionamos nuestro datagridview con nuestro datatable this.dgvDetalle.DataSource = this.dtDetalle; } //Para mostrar mensaje de error private void mError(string mensaje) { MessageBox.Show(this, mensaje, "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Warning); } //Para mostrar mensaje de confirmación private void mOk(string mensaje) { MessageBox.Show(this, mensaje, "MENSAJE", MessageBoxButtons.OK, MessageBoxIcon.Information); } //Evento del clic del boton btnBuscar private void btnBuscar_Click(object sender, EventArgs e) { //Creamos una variable del tipo del formulario que deseamos abrir frmSeleccionarProducto frame = new frmSeleccionarProducto(); //Le pasamos como datos la información de nuestro formulario frame.estableceFormulario(this); //Mostrar el formulario que tiene los productos que hemos seleccionado frame.ShowDialog(); } //Evento clic del boton agregar private void btnAgregar_Click(object sender, EventArgs e) { //Valida que hemos seleccionado algun producto if (this.codigoProductoSeleccionado == -1) { this.mError("No ha seleccionado aun ningun producto"); } else { //Variable que va a indicar si podemos registrar el detalle bool registrar = true; foreach (DataRow row in dtDetalle.Rows) { if (Convert.ToInt32(row["codigoProducto"]) == this.codigoProductoSeleccionado) { registrar = false; this.mError("Ya se encuentra el producto en el detalle"); } } //Si podemos registrar el producto en el detalle if (registrar) { //Calculamos el sub total del detalle sin descuento decimal subTotal = Convert.ToDecimal(this.txtPrecio.Text) * nudCantidad.Value; //Obtenemos el descuento decimal descuento = NegDetalleVenta.ObtenerDescuento( nudCantidad.Value, Convert.ToDecimal(this.txtPrecio.Text)); //Actualizamos el sub total con el descuento correspondiente subTotal = subTotal - descuento; //Aumentamos el total a pagar this.totalPagar += subTotal; this.lblTotalPagar.Text = "Total Pagar: S/." + totalPagar.ToString("#0.00#"); //Agregamos al fila a nuestro datatable DataRow row = this.dtDetalle.NewRow(); row["codigoProducto"] = this.codigoProductoSeleccionado; row["Producto"] = this.txtProducto.Text; row["cantidad"] = this.nudCantidad.Value; row["PU"] = this.txtPrecio.Text ; row["Descuento"] = descuento; row["subTotal"] = subTotal; this.dtDetalle.Rows.Add(row); } } } //Evento click del boton quitar private void btnQuitar_Click(object sender, EventArgs e) { try { //Indice dila actualmente seleccionado y que vamos a eliminar int indiceFila = this.dgvDetalle.CurrentCell.RowIndex; //Fila que vamos a eliminar DataRow row = this.dtDetalle.Rows[indiceFila]; //Disminuimos el total a pagar this.totalPagar = this.totalPagar - Convert.ToDecimal(row["subTotal"].ToString()); this.lblTotalPagar.Text = "Total Pagar: S/." + totalPagar.ToString("#0.00#"); //Removemos la fila this.dtDetalle.Rows.Remove(row); } catch (Exception ex) { mError("No hay fila para remover"); } } private void btnGuardar_Click(object sender, EventArgs e) { //Debe de tener por almenos un detalle para poder registrar if (this.dtDetalle.Rows.Count > 0) { string rpta = NegVenta.Insertar(this.txtCliente.Text, this.dtDetalle); if (rpta.Equals("OK")) { mOk("Se inserto de manera correcta la venta"); this.limpiarControles(); } else { mError(rpta); } } else { mError("No agregado ningun detalle"); } } } }
16 comentarios:
Ola acabo de conocer este tutorial y me gusto mucho ya que esta muy completo... disculpa la ignorancia ya que soy nuevo, hize al pie de la letra lo que muestras en el tutorial pero me marca error. no reconoce txtPrecio ni txtProducto, ademas no se a que te refieres con hacer esos txt de tipo internal. otra cosa que observé es que en tu video se puestra un menú "procesos", ese no lo muestras en ningúna parte, espero puedas responder gracias.
Hola
Haber te explico los txt son los nombres de la caja de texto.
Que quiere decir que un txt sea internal, que tienes q cambiar su propiedad de accesibilidad.
El menu tu lo tienes que agregar, ya depende de como tu lo llames a los formularios.
JEJEJE gracias... no conocia el termino "internal", imagino que te referias a que los txt tenian que ser públicos ya que con eso me funcionó, y gracias por aclararme que yo debo de agregar el menú, no sabia si estaba incompleto el tutorial... ahora solo me queda felicitarte por tu gran trabajo, totoriales tan completos y en español no se encuentran facilmente... saludos!!!
JEJEJE gracias... no conocia el termino "internal", imagino que te referias a que los txt tenian que ser públicos ya que con eso me funcionó, y gracias por aclararme que yo debo de agregar el menú, no sabia si estaba incompleto el tutorial... ahora solo me queda felicitarte por tu gran trabajo, totoriales tan completos y en español no se encuentran facilmente... saludos!!!
Public es diferente con internal ... Te paso la documentación
http://msdn.microsoft.com/es-es/library/7c5ka91b(v=vs.80).aspx
Son términos distintos. Que bueno que te haya servido. Síguenos visitando
Excelente tutorial, muy pocas veces me queda algo tan claro, fueron muchas horas de Esfuerzo pero entendi, mil gracias.
Pocos Blogs con contenido tan util hay en internet.
Gracias por el comentario, siempre síguenos en nuestros tutoriales.
Me Marca un Error en
this.frame.txtProducto.Text = Convert.ToString(this.dgvProducto.CurrentRow.Cells["nombre"].Value);
this.frame.txtPrecio.Text = Convert.ToString(this.dgvProducto.CurrentRow.Cells["precio"].Value);
Esto es del "frmSeleccionarProducto", según la imagen no hay controles,
pero en el codigo parece que si
Haber los txt del formulario de frmRegistrarVenta lo tienes que declarar con accesibilidad publica o internal para que puedas acceder a los valores de esas variables. Saludos!!!
Hola, ante todo gracias por el tutorial, noto que más de 1 estamos teniendo problemas al intentar re-crear tu proyecto, podrias ponerlo como descarga??, tal vez si lo subieras a Mediafire.
Gracias!!
La solución lo pueden encontrar en el resumen del tutorial.
http://www.programandoconcafe.com/2011/02/sistemas-de-ventas-con-c-resumen.html
Saludos
El Tutorial esta perfecto, en lo único que me atoré en un principio fue en poner publicas o internal los textbox, y si acaso en que en el tutorial no te dice que tu le agregas el menú, pero por todo lo demás funciona al 100%. Ademas que mejor que batallar un poquito y preguntar para que le entendamos. exelente tuto Henry me ayudo mucho...
Que bueno que te haya servido. Saludos
Hola, de verdad que es un excelente tutorial y le agradezco por brindarnos la oportunidad de acceder a esta información.
Ahora, tengo un problema, necesito realizar una consulta y cargar los datos en un dataGridView pero los datos deben ser cargados luego de dar clic en el boton Consultar y para ello debe ingresar un parametro de busqueda; espero que me pueda ayudar con este problema. Le dejo el código que estoy utilizando.
De ante mano, MUCHAS GRACIAS.
//PROCEDIMIENTO
CREATE PROCEDURE ConsultaVacuna
(
@nombre Varchar(20)
)
AS
SELECT *
FROM vacuna
WHERE nombre=@nombre
Return
//ACCESO DATOS
public DataTable Consultar(string nom)
{
DataTable DT_Vacuna = new DataTable("vacuna");
SqlConnection Scn = MiConexion.ConectarBD();
try
{
Scn.ConnectionString = ConexionBD.cn;
SqlCommand Scm = new SqlCommand();
Scm.Connection = Scn;
Scm.CommandText = "ConsultaVacuna";
Scm.CommandType = CommandType.StoredProcedure;
Scm.Parameters.AddWithValue("@nombre", nom);
SqlDataAdapter sqlDat = new SqlDataAdapter(Scm);
sqlDat.Fill(DT_Vacuna);
}
catch (Exception ex)
{
DT_Vacuna = null;
}
return DT_Vacuna;
}
//LOGICA
public static DataTable Consultar(string nom)
{
DataTable DtVacuna;
AcessoDatos.vacuna va = new AcessoDatos.vacuna();
DtVacuna = va.Consultar(nom);
return DtVacuna;
}
//PRESENTACION
private void btnConsultar_Click(object sender, EventArgs e)
{
if (txtNombre.Text == "")
{
MessageBox.Show("Faltan datos");
}
else
{
logica.vacuna va = new logica.vacuna();
dataGridView1.DataSource = logica.vacuna.Consultar(txtNombre.Text);
dataGridView1.Refresh();
}
}
buen tutorial, excelente.
buen tutorial, excelente.
Publicar un comentario