none
Tipo de control para mostrar varias imagenes RRS feed

  • Pregunta

  • Muy bunos dias a todos. nuevamente pidiendo ayuda.

    estoy en eso de hacer un pequeño sistema para venta de panes empanadas y otros simulando una tienda por lo cual me levantan dudas al respecto y en el Internet si bien hay ejemplos aveces es necesario mas ayuda. 

    por tanto hoy quiero preguntar a uds. estimados quiero llegar mas o menos a esto que mostrare en la imagen.

    por ejemplo cuando en esta imagen se presiona la categoría bebidas, en el recuadro de la derecha se despliegan todas las imágenes de bebidas. pregunto que control hace esto, y la verdad no se que es mas recomendable traer mediante una consulta las imágenes desde la BD o desde una carpeta.

    pero lo que quiero es que al presionar por ejemplo EL btnPan Me muestre todos las fotos de la categoría PAN en el recuadro de la derecha.

    por favor que me pueden decir al respecto.

    Gracias

    Roberto

    jueves, 12 de marzo de 2020 14:58

Respuestas

  • Hola Roberto

    A ver cómo hacemos los botones de las Categorías y al hacer click, los botones de los productos ...

    // 1° Declarar miembros de clase
    
    private List<Button> botonesCategorias;
    private List<Button> botonesProductos;
    
    // 2° Con Entity Framework (que yo no lo se usar) conseguis un List<Categoria> categorias (si queres te lo hago en ADO.NET pero me dijiste que no)
    
    Button boton;
    botonesCategoria = new List<Button>();
    foreach (var categoria in categorias)
    {
        boton = new Button();
        // ver cuanto es ancho y alto
        boton.Size = new Size(ancho, alto);
        // ver cuanto es x e y
        boton.Location = new Point(x, y);
        // la imagen guardada en la base de datos
        boton.Image = categoria.Imagen;
        // el nombre de la categoría
        boton.Text = categoria.Nombre;
        // el ID de la categoría
        boton.Tag = categoria.ID.ToString();
        boton.Click += new EventHandler(botonCategoria_Click);
        botonesCategoría.Add(boton);    
    }
    
    // 3° el método botonCategoria_Click
    private void botonCategoria_Click(object sender, EventArgs e) 
    {
        Button boton = (Button)sender;
        string ID = boton.Tag;
        
        // con el ID conseguis todos los Productos cuya categoría es la misma del botón sobre el cual se clickeó
        // Con EF haces un List de todos esos Productos
        
        Button boton;
        botonesProductos = new List<Button>();
        foreach (var producto in Productos)
        {
            boton = new Button();
            boton.Size = new Size(ancho, alto);
            boton.Location = new Point(x, y);
            boton.Image = producto.Imagen;
            boton.Text = producto.Nombre;
            boton.Tag = producto.ID.ToString();
            boton.Click += new EventHandler(botonProducto_Click);
        }    
    }
    
    private void botonProducto_Click(object sender, EventArgs e) 
    {
        Button boton = (Button)sender;
        string ID = boton.Tag;
    
        // Aquí con el ID haces lo que queres con el Producto, vender, o lo que sea
    }

    Fijate que los métodos del evento Click, tanto para los botones de Categoría como para los de Productos, son los mismos, sólo que en cada llamado diferencian qué botón los llamó por el ID que viene en el Tag del Button, te acordas? 

    Sólo te faltaría a vos llenar lo de Entity Framework, que yo desconozco, y en el método del Click de Producto, ver qué vas a hacer con el Producto para ponerlo en la lista de Venta o lo que quieras.

    Decime si me faltó algo ... que no sea lo del EF por favor.

    Saludos

    Pablo

    viernes, 17 de abril de 2020 2:42

Todas las respuestas

  • Disculpen esta es la imagen

    jueves, 12 de marzo de 2020 15:21
  • Hola Roberto

    La barra de arriba sería un ToolStrip y lo de la derecha abajo un Panel con botones dinámicos. A todos los botones, tanto los del ToolStrip como los "comunes" del menú de la derecha abajo les podes asignar el tamaño que quieras y una imagen. 

    ¿Me captas la idea o te hago un ejemplo básico? No es una UI tan simple. Pero se hace tranquilamente.

    Saludos

    Pablo

    jueves, 12 de marzo de 2020 18:29
  • Tigre Pablito

    eso de ToolStrip entendido, ahora eso de Panel con botones dinámicos que control sería. la verdad es nuevo para mi.

    ¿Me captas la idea o te hago un ejemplo básico? No es una UI tan simple. Pero se hace tranquilamente.

    la verdad agradezco todo tipo de ayuda ya que deseo hacer algo así.

    Gracias

    Roberto

    jueves, 12 de marzo de 2020 18:43
  • hola

    >>en el recuadro de la derecha se despliegan todas las imágenes de bebidas. pregunto que control hace esto,

    Podrias evaluar el control Repeter, este viene como parte del power pack

    VisualBasic PowerPack missing from Visual Studio 2013?

    Using Visual Basic PowerPack DataRepeater control in Visual Studio 2013

    podrias pones datos y la imagen en el template

    saludos


    Leandro Tuttini

    Blog
    MVP Profile
    Buenos Aires
    Argentina

    jueves, 12 de marzo de 2020 18:54
  • Estimado Leandro gracias.

    este control me viene bien, y la verdad no lo conocía, solo que creo que son dos columnas y yo necesito un tabulado por la cantidad de imágenes que tenga.

    o no es cierto?

    gracias 

    Roberto

    jueves, 12 de marzo de 2020 19:10
  • Hola Roberto

    Te paso una base del programa, para que tengas una idea y lo puedas continuar. Si tenes otra duda, pregunta de nuevo. Por ahora lo que hace es, al dar click en el botón bebidas, muestra 3 botones (con 3 bebidas) en el Panel, y al dar click en el botón sopas, resetea el List<Button> botones y borra todos los Controles (sólo botones) del Panel.

    EDITO:

    Para avisar que tenes que tener, para ejecutar esta base, en la carpeta Debug del proyecto, las imágenes "sopas.png" y "bebidas.png", y en una carpeta "bebidas" dentro de Debug, las imágenes "seven up.png", "agua mineral.png" y "no se que es.png" (las 3 primeras bebidas usé yo). Podes cambiar los nombres y las imágenes si queres.

    Primero el archivo Designer.cs y luego el .cs.

    namespace WinFormsMiniBarApp
    {
        partial class Form1
        {
            /// <summary>
            /// Required designer variable.
            /// </summary>
            private System.ComponentModel.IContainer components = null;
    
            /// <summary>
            /// Clean up any resources being used.
            /// </summary>
            /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
            protected override void Dispose(bool disposing)
            {
                if (disposing && (components != null))
                {
                    components.Dispose();
                }
                base.Dispose(disposing);
            }
    
            #region Windows Form Designer generated code
    
            /// <summary>
            /// Required method for Designer support - do not modify
            /// the contents of this method with the code editor.
            /// </summary>
            private void InitializeComponent()
            {
                System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Form1));
                this.toolStrip1 = new System.Windows.Forms.ToolStrip();
                this.toolStripButton1 = new System.Windows.Forms.ToolStripButton();
                this.panel1 = new System.Windows.Forms.Panel();
                this.toolStripButton2 = new System.Windows.Forms.ToolStripButton();
                this.toolStrip1.SuspendLayout();
                this.SuspendLayout();
                // 
                // toolStrip1
                // 
                this.toolStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
                this.toolStripButton1,
                this.toolStripButton2});
                this.toolStrip1.Location = new System.Drawing.Point(0, 0);
                this.toolStrip1.Name = "toolStrip1";
                this.toolStrip1.Size = new System.Drawing.Size(847, 113);
                this.toolStrip1.TabIndex = 0;
                this.toolStrip1.Text = "toolStrip1";
                // 
                // toolStripButton1
                // 
                this.toolStripButton1.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
                this.toolStripButton1.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton1.Image")));
                this.toolStripButton1.ImageScaling = System.Windows.Forms.ToolStripItemImageScaling.None;
                this.toolStripButton1.ImageTransparentColor = System.Drawing.Color.Magenta;
                this.toolStripButton1.Name = "toolStripButton1";
                this.toolStripButton1.Size = new System.Drawing.Size(110, 110);
                this.toolStripButton1.Text = "toolStripButton1";
                this.toolStripButton1.Click += new System.EventHandler(this.toolStripButton1_Click);
                // 
                // panel1
                // 
                this.panel1.BackColor = System.Drawing.SystemColors.ControlDark;
                this.panel1.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
                this.panel1.Dock = System.Windows.Forms.DockStyle.Right;
                this.panel1.Location = new System.Drawing.Point(327, 113);
                this.panel1.Name = "panel1";
                this.panel1.Size = new System.Drawing.Size(520, 384);
                this.panel1.TabIndex = 1;
                // 
                // toolStripButton2
                // 
                this.toolStripButton2.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
                this.toolStripButton2.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton2.Image")));
                this.toolStripButton2.ImageScaling = System.Windows.Forms.ToolStripItemImageScaling.None;
                this.toolStripButton2.ImageTransparentColor = System.Drawing.Color.Magenta;
                this.toolStripButton2.Name = "toolStripButton2";
                this.toolStripButton2.Size = new System.Drawing.Size(110, 110);
                this.toolStripButton2.Text = "toolStripButton2";
                this.toolStripButton2.Click += new System.EventHandler(this.toolStripButton2_Click);
                // 
                // Form1
                // 
                this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
                this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
                this.ClientSize = new System.Drawing.Size(847, 497);
                this.Controls.Add(this.panel1);
                this.Controls.Add(this.toolStrip1);
                this.Name = "Form1";
                this.Text = "Form1";
                this.toolStrip1.ResumeLayout(false);
                this.toolStrip1.PerformLayout();
                this.ResumeLayout(false);
                this.PerformLayout();
    
            }
    
            #endregion
    
            private System.Windows.Forms.ToolStrip toolStrip1;
            private System.Windows.Forms.ToolStripButton toolStripButton1;
            private System.Windows.Forms.Panel panel1;
            private System.Windows.Forms.ToolStripButton toolStripButton2;
        }
    }
    using System;
    using System.Collections.Generic;
    using System.Drawing;
    using System.IO;
    using System.Windows.Forms;
    
    namespace WinFormsMiniBarApp
    {
        public partial class Form1 : Form
        {
            private List<Button> botones;
            
            public Form1()
            {
                InitializeComponent();
            }
    
            private void toolStripButton2_Click(object sender, EventArgs e)
            {
                CargarBebidas();
            }
    
            private void CargarBebidas() 
            {
                int a;
                if (botones == null) 
                    botones = new List<Button>();
                botones.Clear();
    
                string[] imagenes = Directory.GetFiles("bebidas", "*.png");
    
                foreach (string imagen in imagenes) 
                {
                    botones.Add(new Button());
                }
    
                for (a = 0; a < botones.Count; a++)
                {
                    botones[a].Image = new Bitmap(imagenes[a]);
                    botones[a].Size = new Size(106, 106);
                    botones[a].Location = new Point(a * 106, 0);
                }
    
                panel1.Controls.Clear();
                panel1.Controls.AddRange(botones.ToArray());
            }
    
            private void toolStripButton1_Click(object sender, EventArgs e)
            {
                int a;
                if (botones == null)
                    botones = new List<Button>();
                botones.Clear();
    
                panel1.Controls.Clear();
            }
        }
    }

    Espero te sea útil.

    Saludos



    jueves, 12 de marzo de 2020 20:04
  • Estimado Tigre

    entiendo que para esto necesito dos formularios y una carpeta con imagenes no es cierto

    o me corrigue por favor

    Gracias

    Roberto

    jueves, 12 de marzo de 2020 20:19
  • Una carpeta con imágenes, sí. Podes copiarlas de la imagen que mostraste. Y más de un form, no se, parecería como que está todo lo necesario en el form principal que mostraste, quizás un form chiquito para ingresar las cantidades de los artículos que vas vendiendo, y también, para ingresar los datos del stock, pero no creo que más que eso.

    Igual, si fuesen necesarios más forms, los vas agregando, eso no es muy difícil.
    jueves, 12 de marzo de 2020 20:28
  • hola

    >>solo que creo que son dos columnas y yo necesito un tabulado por la cantidad de imágenes que tenga.

    Entiendo la cantidad de columnas va a depender del tamaño del template y la orientacion que definas en el Repeter

    LayoutStyle

    saludos


    Leandro Tuttini

    Blog
    MVP Profile
    Buenos Aires
    Argentina

    jueves, 12 de marzo de 2020 20:33
  • Estimado Tigre me queda este error.

    Claramente me dice que falta el directorio o no es cierto.

    muchas gracias voy avanzando

    Roberto

    jueves, 12 de marzo de 2020 20:46
  • Estimado Roberto

    Claro, como te mencioné antes, tendrías que tener en tu carpeta Debug las imágenes "sopas.png" y "bebidas.png", y allí en la misma carpeta Debug también una carpeta "bebidas" que contenga las imágenes "seven up.png", "agua mineral.png" y "no se que es.png" (las 3 primeras bebidas), yo las copié de la imagen que vos mostraste para probar la aplicación.

    jueves, 12 de marzo de 2020 21:11
  • Estimado, así va quedando

    voy avanzando, de verdad muchas gracias.

    ahora veo que las imágenes no se adaptan al contenedor dinámico

    creo que es porque hay que cambiar algunas propiedades, esto porque coloque en la carpeta mas de tres imagenes.

    voy avanzando.

    Gracias

    Roberto

    jueves, 12 de marzo de 2020 21:15
  • Para que te deje las imágenes del tamaño que son en el ToolStrip, le tenes que asignar a la propiedad ImageScaling de cada botón (ToolStripButton) el valor None. Ya está así en el ejemplo que te pasé.
    jueves, 12 de marzo de 2020 21:25
  • La verdad no encuentro la propiedad ImageScaling, pero que le parece que pueda usa el control flowlayoutpanel o le pregunto porque uso este y no el que me había mencionando al principio por favor, que no se entienda como cuestionamiento sino como duda del porque opto por Panel y no por el otro por favor

    Gracias

    jueves, 12 de marzo de 2020 21:30
  • Si haces click con el botón derecho del mouse sobre un botón del ToolStrip, y en el menú emergente haces click en Propiedades, se muestra a la derecha del editor una ventana con las mismas y sus valores iniciales o por omisión, y están en orden alfabético. Allí podes buscar la propiedad ImageScaling de cada botón del ToolStrip y ponerla a None, y así se verán las imágenes en tamaño real. 

    Todo bien, se puede usar el FlowLayoutPanel, el estilo y la forma de codificar o diseñar está en cada uno, a mi me parece que no es necesario porque se pueden colocar los botones "normales", con su imagen y todo, en el Panel, de forma tabular con una fórmula muy simple, sin necesidad de agregar un control como el FlowLayoutPanel y el exceso de código que el mismo implica. Se puede simplificar eso, con sólo asignar al ancho y alto del Panel un número múltiplo del ancho y alto de las imágenes, y luego al asignar la propiedad Location (fijate en el código que te pasé) de cada botón se usa esta fórmula (suponiendo que el lado, ancho y alto de la imagen es 106, y suponiendo que anchoPanel es el ancho del Panel dividido 106):

    botones[a].Location = new Point(a % anchoPanel * 106, a / anchoPanel * 106);
    Vos elegí lo que quieras, yo te sigo ayudando igual.

    jueves, 12 de marzo de 2020 21:52
  • Así quedo con el flowlayoutpanel  y de momento por favor me gustaria quedarme con este ya posteriormente vere lo del tamaño de la imagen.

    esta es la imagen

    ahora estimado Tigre, ya tengo la imagen aquí al dar click yo necesito que las propiedades de ese producto se me coloquen en una lista ahora mostrare el formulario para mas claridad 

    la pregunta esto es posible mi idea es esta 

    supongamos que mi imagen se llame pantrigo.png

    podría yo hacer un select a mi bd de esta manera 

    select id, codigo,descripcon, precio from tblproducto where codigo = pantrigo

    claro esta que el codigo del producto debe tener el mismo nombre que el nombre de la imagen

    pregunto esto es mas o menos factible o cual seria la forma de hacer esto

    muchas gracias

    sigo avanzando

    Roberto 

    jueves, 12 de marzo de 2020 22:19
  • Si, la consulta está bien

    SELECT id, codigo, descripcion, precio FROM tblproducto WHERE codigo = 'pantrigo'

    pero si codigo es un string (varchar o nchar o algo así) entonces pantrigo va entre comillas simples. No necesariamente tiene que tener el mismo nombre de la imagen, excepto que la imagen la guardes en el campo codigo de la tabla. 

    Cuál sería la forma de hacer qué, exactamente? Que aparezcan los datos en la lista de abajo a la izquierda? Primero hay que diseñar esa parte en la UI (interfaz de usuario).

    jueves, 12 de marzo de 2020 22:47
  • Estimado gracias no me queda claro aun esta parte

    No necesariamente tiene que tener el mismo nombre de la imagen, excepto que la imagen la guardes en el campo código de la tabla. 

    pero mi formularios me gustaría que sea este, pueda que hayan cambios y también, bienvenida las sugerencias por favor.

    a lo que entiendo primero debo crear el evento Click del boton, mi gran duda y me asusta es:

    como va a saber el sistema que precione el boton donde estaba dibujado el panTrigo y luego eso debe ir a bd y traer la tupla y colocar en la lista que esta a la derecha.

    sigo avanzando estimado.

    Gracias

    Roberto

    jueves, 12 de marzo de 2020 22:55
  • como va a saber el sistema que precione el boton donde estaba dibujado el panTrigo y luego eso debe ir a bd y traer la tupla y colocar en la lista que esta a la derecha. 

    Lo que tendrías que hacer es un vector de codigos, o uno por cada categoría. El método controlador del evento Click de los botones va a ser el mismo para todos (ya que todos los productos tienen la misma estructura o las mismas propiedades, aunque las mismas no tienen los mismos valores, pero de esto último se encargará el índice).

    O sea, en concreto, suponiendo que los siguientes son los productos de la categoría "bebidas".

    string[] bebidas = new string[] {
        "sevenUp",
        "aguaMineral",
        "cerveza",
        "cocaCola",
        "jugoFrutas"
    };

    Armas así el vector, los string del mismo serían los nombres de los códigos (del campo codigo de la tabla), y deben ir en el mismo orden que las correspondientes imágenes, y cuando haces click en uno de los botones, obtenes el índice (que no se como se hace, pero debe haber una propiedad del FlowLayoutTable que te de el índice de sobre cual casilla hiciste click), y en el método del evento click al hacer la consulta, que me imagino que es un string que se lo pasas a un SqlCommand, en lugar de poner 'pantrigo', pones bebidas[indice], así:

    string consulta = "SELECT id, codigo, descripcion, precio FROM tblproducto WHERE codigo = '" + bebidas[indice] + "'";
    
    Aunque lo más usual es tener ya cargados en memoria (en un List<> por ejemplo) todos los productos. 

    jueves, 12 de marzo de 2020 23:52
  • Estimado Tigre buen día.

    Dios lo bendiga.

    he leido detenidamente el ultimo mensaje pero aun no logro entenderlo y he pensado que para entenderlo debo primero volverlo cada vez mas real vale decir he analizado los métodos.

    por ejemplo este metodo

    private void CargarBebidas()
            {
                int a;
                if (botones == null)
                    botones = new List<Button>();
                botones.Clear();
    
                //string[] imagenes = Directory.GetFiles("bebidas", "*.png"); ////Original
                string[] imagenes = Directory.GetFiles(@"C:\Bebidas", "*.png");
                foreach (string imagen in imagenes)
                {
                    botones.Add(new Button());
                }
                for (a = 0; a < botones.Count; a++)
                {
                    botones[a].Image = new Bitmap(imagenes[a]);
                    botones[a].Size = new Size(106, 106);
                    botones[a].Location = new Point(a * 106, 0);
                    //botones[a].Location = new Point(a % 1236 * 106, a / 1236 * 106);
                }
                //panel1.Controls.Clear();
                //panel1.Controls.AddRange(botones.ToArray());
                flowLayoutPanel1.Controls.Clear();
                flowLayoutPanel1.Controls.AddRange(botones.ToArray());
            }

    que es llamada desde el botón de arriba

    private void toolStripButton2_Click_1(object sender, EventArgs e)
            {
               
                CargarBebidas();
                
                
            }

    entonces debo tener tantos métodos como categorías tenga.(es lo que pienso) porque dentro del método va el directorio adonde debe ir a buscar las imágenes.

    pero se me ocurrió lo siguiente si en Tag. del botón coloco el directorio por ejemplo ya lo estaba haciendo.

    y así en cada botón usar el mismo método pero que me busque el Tag. de cada Botón.

    vuelvo a decir es lo que pienso, ahora 

    pregunto esto es factible o hay otra forma mas simple o técnicamente mas mejor de resolver esto.

    yo intentando hacer con esto me sale este error pero antes miren como me muestra el directorio en una cadena obtenida del Tag.

    con este código

     //CargarBebidas();
                string Cadena = "@"+'"' + TsbBebidas.Tag.ToString() + '"';
                MessageBox.Show(Cadena);

    pero ya cuando lo pongo a correr me sale un error el cual no puedo resolver.

    Como puedo por favor resolver este problema.

    Porque me detuve en este paso, pues porque quiero tener dos botones por lo menos para que las pruebas sean mas reales, lo de como saber que btn presione lo veré luego que tenga por lo menos dos escenarios mas reales.

    Gracias espero por ayuda 

    gracias Tigre

    Roberto

    viernes, 13 de marzo de 2020 13:19
  • Estimados lo logre haciendo esto

    anterior

    string[] imagenes = Directory.GetFiles(dir, "*.png");

    nuevo agregue @ a dir

    string[] imagenes = Directory.GetFiles(@dir, "*.png");

    viernes, 13 de marzo de 2020 13:53
  • Hola Roberto

    El @ va adelante de un string para poder escribir cosas como la barra invertida una sola en lugar de 2 veces, por ejemplo:

    "C:\\ProductosGourmet\\Pan\\"

    se puede escribir como 

    @"C:\ProductosGourmet\Pan\"

    o sea si escribis el @ delante de la doble comilla inicial, los caracteres como la barra invertida que va doble la anotas simple. 

    Si, tendrías que hacer un método del evento click por cada categoría, o creo que también podrías hacer uno solo genérico.

    Acerca de las carpetas o directorios, no es usual usar la raíz C:\ ... y cuando yo puse la carpeta "bebidas" así relativo, se suponía que estaba en la carpeta donde está el ejecutable (.exe), esto es, Debug.

    viernes, 13 de marzo de 2020 18:10
  • Gracias por la explicación anterior.

    ahora con relación al método que extrae las imágenes hice esto 

    private void CargarBebidas(string directorio)
            {
                int a;
                if (botones == null)
                    botones = new List<Button>();
                botones.Clear();
                string[] imagenes = Directory.GetFiles(@directorio, "*.png");
                foreach (string imagen in imagenes)
                {
                    botones.Add(new Button());
                }
                for (a = 0; a < botones.Count; a++)
                {
                    botones[a].Image = new Bitmap(imagenes[a]);
                    botones[a].Size = new Size(106, 106);
                    botones[a].Location = new Point(a * 106, 0);
                    //botones[a].Location = new Point(a % 1236 * 106, a / 1236 * 106);
                }
    
                //panel1.Controls.Clear();
                //panel1.Controls.AddRange(botones.ToArray());
                FlpImagenProductos.Controls.Clear();
                FlpImagenProductos.Controls.AddRange(botones.ToArray());
            }

    y ahora tengo dos botones de ejemplo con imagenes

    una para a la carpeta principal le llame ProductosGourmet (por ponerle un nombre)

    dentro cree dos carpetas una para Pan y la Otra bebidas

    en el Tag de cada toolStripButton asigne el directorio y funciona  y llamo desde cada boton del toolStripButton y funciona

    private void TsbBebidas_Click(object sender, EventArgs e)
            {
                var btn = (ToolStripButton)sender;
                string directorio = btn.Tag.ToString();
                CargarBebidas(directorio);
            }


    y el otro

     private void TsbSopas_Click(object sender, EventArgs e)
            {
                var btn = (ToolStripButton)sender;
                string Cadena = btn.Tag.ToString();
                CargarBebidas(Cadena);
    
            }

    y pues creo que si funciona con dos ya puede funcionar con mas carpetas.

    Estimado Tigre Gracias.

    con relación a este párrafo

    Acerca de las carpetas o directorios, no es usual usar la raíz C:\ ... y cuando yo puse la carpeta "bebidas" así relativo, se suponía que estaba en la carpeta donde está el ejecutable (.exe), esto es, Debug.

    No es usual usar la raíz por favor, por favor que sería lo mejor.

    ahora porque lo hago así. (Lo que pienso, y tal vez no este bien)

    tengo pensado que, cuando ponga el sistema en producción el propietario del sistema va a tener que cargar sus propias fotos crear sus propios directorios y definir tantas carpetas necesite, porque según yo tengo entendido que una vez yo hago el ejecutable la carpeta Debug ya no la puedo modificar.

    por favor seria agradecido yo por las correcciones de su persona. y las indicaciones para seguir adelante.

    Gracias Tigre.

    Roberto

    viernes, 13 de marzo de 2020 19:00
  • Estimado Roberto

    Trato de responderte en orden.

    1) No se usa el @ delante de las variables de tipo string, sino delante de los valores string. Por ejemplo:

    string directorio = "C:\\ProductosGourmet\\Pan\\";

    se puede simplificar como

    string directorio = @"C:\ProductosGourmet\Pan\";

    pero no se usa

    @directorio

    2) Podes llamar al método CargarProductos() en lugar de CargarBebidas(), ya que lo estás haciendo genérico, lo cual me parece muy bien. 

    Lo de asignar a Location de los botones no se (creo que si) si es innecesario o está mal, porque me imagino que deberías asignarle los casilleros del FlowLayoutPanel, que te debería colocar directamente los botones en cada casillero, no se como se hace porque nunca lo usé, pero debe ser fácil.

    3) Si usas una carpeta y no la especificas completa la ruta (absoluta), entonces busca en el carpeta en donde está el ejecutable, que es la carpeta Debug. Y si, se puede usar cualquier carpeta para poner las carpetas con las imágenes. Lo usual es tener una carpeta con todo (carpetas y archivos) en el mismo lugar que el .exe.

    4) Si lo vas a hacer que el usuario pueda inventar sus propios productos con sus imágenes y sus carpetas, la aplicación va a ser un poco más compleja y no tan fácil como viene siendo por ahora. Pero todo se puede hacer.

    viernes, 13 de marzo de 2020 19:29
  • Muya amable gracias.

    1) entonces quedo de esta manera ya que lo traigo desde el Tag

    en el Tag esta el directorio

     private void TsbBebidas_Click(object sender, EventArgs e)
            {
                var btn = (ToolStripButton)sender;
                string directorio = @btn.Tag.ToString();
                CargarProducto(directorio);
            }

    2) Ya cambie el nombre del metodo, 

    ahora, lo que entiendo de 

    3) Si usas una carpeta y no la especificas completa la ruta (absoluta), entonces busca en el carpeta en donde está el ejecutable, que es la carpeta Debug

    es que si tengo en el Debug una Carpeta llamada ProductosGourmet y dentro de ella carpetas llamadas

    Pan , Bebidas, platos, etc, 

    busca dentro de la carpeta ProductosGourmet por mas que en el Tag me diga C:\\ProductosGourmet

    esta bien lo que entiendo o muy mal.

    ahora estimado del porque mi idea de que el propietario cree sus carpetas, porque. que pasaría si luego de entregarle el aplicativo el propietario quiere agregar mas fotos y mas carpetas debería buscarme o como funciona esto por favor.

    gracias. 

    ya se viene lo mas interesante que es capturar el nombre del botón creado dinamicamente. La verdad me asusta un por esta parte, pero se que podremos hacerlo.

    muchas gracias Tigre.

    Roberto

    viernes, 13 de marzo de 2020 20:42
  • El nombre del método sería CargarProductos() en plural, porque carga todos los productos de una categoría, ... aunque eso no es TAN importante.

    Si vas a poner la carpeta "ProductosGourmet" en la carpeta "Debug" entonces tendrías que omitir el C:\\ en el Tag, con lo cual quedaría como una ruta (o Path) relativa y te lo buscaría en la carpeta Debug que es donde está el .exe.

    Para que el usuario pueda elegir y agregar sus propios productos e imágenes, tendrías que implementar un mecanismo de entrada de datos que involucra UI (interfaz de usuario), código, y base de datos. También podes escribir una explicación para el usuario (además de diseñar el sistema amistoso e intuitivo) y/o hacerle a cada uno sus propios productos en su aplicación o una demostración así aprenden.

    Una cosa que creo importante que te mencioné antes que no se si recordas, es que habría que tener todos los productos cargados en una lista, así podes acceder fácilmente y no tenes que estar constantemente realizando consultas a la base de datos.

    El "nombre" del botón no lo hemos definido, excepto llamarlo por su índice en el List<Button> botones, pero eso no tiene importancia, sino el nombre del producto que vas a vender (o incluir en la lista de los que vas a vender).


    viernes, 13 de marzo de 2020 21:30
  • Muy bien.

    esto es precisamente lo que deseo hacer al respecto de este tema

    Para que el usuario pueda elegir y agregar sus propios productos e imágenes, tendrías que implementar un mecanismo de entrada de datos que involucra UI (interfaz de usuario), código, y base de datos. También podes escribir una explicación para el usuario (además de diseñar el sistema amistoso e intuitivo) y/o hacerle a cada uno sus propios productos en su aplicación o una demostración así aprenden.

    luego ya creo esa interfaz

    tengo los productos en mi base de datos. y este es ya algo preliminar ya estoy trayendo los productos de ba bd

    este es un visor de mis productos por categoría.

    esta parte por favor, por favor Tigre no la entiendo

    Una cosa que creo importante que te mencioné antes que no se si recordas, es que habría que tener todos los productos cargados en una lista, así podes acceder fácilmente y no tenes que estar constantemente realizando consultas a la base de datos.

    esto lo debo traer de la base de datos o de la carpeta porque si es de la base de datos tengo este código

    using (GourmetEntities db = new GourmetEntities())
                {
    
                    var Lista = from Datos in db.tblProductoes
                                where Datos.IdCategoria == id
                                select new
                                {
                                    Datos.Id,
                                    Datos.Codigo,
                                    Datos.Descripcion,
                                    Datos.PrecioVenta,
                                    Datos.Stock
                                };
                    foreach (var item in Lista)
                    {
    
                        ListViewItem _item = new ListViewItem();
    
                        _item = listView1.Items.Add(item.Id.ToString());
                        _item.SubItems.Add(item.Codigo);
                        _item.SubItems.Add(item.Descripcion);
                        _item.SubItems.Add(item.PrecioVenta.ToString());
    
                    }
                }

    por favor me corrige, por favor.

    y el ejercicio que me gustaria hacer y no voy a negar que me tiene curioso es como el programa va a saber que el boton que presione es panTrigo 

    por favor sigo avanzando por favor

    Gracias

    Roberto

    viernes, 13 de marzo de 2020 21:55
  • Roberto, para que al dar click en un botón sepa cual producto es, como te dije antes, tendrías que tener un vector (o array, o matriz) de nombres de los productos de cada categoría, en el mismo orden los string que los botones en la lista. Así cuando das click a un botón obtenes el índice (que eso me imagino te lo da de alguna forma el FlowLayoutPanel) y con ese índice obtenes del vector el nombre o código del producto. 

    Por ejemplo:

    string[] codigosBebidas = new string[] {
        "sevenUp",
        "aguaMineral", 
        "cerveza",
        "cocaCola", 
        "jugoFrutas"
    };
    
    int indice = flowLayoutPanel1.SelectedIndex; // supongo que debe ser algo así
    
    string consulta = "SELECT id, codigo, descripcion, precio, stock FROM tblproductos WHERE codigo = '" + codigosBebidas[indice] + "'";
    

    Aunque si vamos a tener cargados los productos en un List<> no va a ser necesario la consulta anterior sino que accederemos a la lista a través del índice para obtener los datos del producto seleccionado.

    Te pregunto algo: me parece que quizás es mejor que vayamos por partes. Por ejemplo, primero abocarnos a la parte de selección de productos para vender, y luego a la de ingreso de datos, o viceversa. O sea, no digo que si vamos primero por una no me puedas preguntar por otra cosa, sino que tratemos de ir más firme. Como prefieras. 

    Te digo esto porque me preguntas sobre la carga de la lista, y para eso tienen que haber ya cargados productos en la base de datos. Y la idea es, creo, que cada usuario los ingrese a su forma. Lo que si, no te preocupes, que se puede hacer todo, y lo que es necesario se modifica, no es TAN difícil tampoco este programa.

    Para cargar en memoria la lista de productos, se define una clase con los atributos de los productos, y se crea un List<Producto> para almacenarlos. Se hace una consulta a la base de datos y se cargan en ese List todos los productos. Una cosa que no se si mencioné, un atributo de la tabla productos debe ser una FK a la tabla categorias, que especifica justamente a cual categoría pertenece. 

    Una cosa que me asusta: estás usando Entity Framework? Te soy franco, no se usarlo, no me gusta y me parece un espanto que es re complicado, limitado, y es una invitación al error y al conflicto (además de que está hecho internamente con T-SQL natural), me parece mucho más práctico y fácil usar directamente el lenguaje Transact-SQL y SqlCommand y ADO.NET. Pero bueno, es tu decisión las herramientas que usas o no, yo sólo te sugiero lo que me parece.

    viernes, 13 de marzo de 2020 23:00
  • Estimado Tigre, buen día.

    gracias por la sugerencia de ir por partes, y en lo personal también creo que es lo mejor.

    voy a responder a esta ultima respuesta no en orden por esta vez.

    Sí. estoy Utilizando EF ya que lo hago para aprender ya que antes había usado DS, coincido en lo poco que voy viendo que es un poco limitado, pero la verdad deseo aprenderlo.

    ahora me gustaría mostrar lo que tengo referente a los productos, haré algunas capturas para que tal vez sea mas rápido de verlo.

    algunas tablas no tienen sentido de estar, ya que son pruebas (Como le dije estoy practicando)

    tengo tambien sus clases

    public partial class tblProducto
        {
            public int Id { get; set; }
            public int IdCategoria { get; set; }
            public int IdUnidadMedida { get; set; }
            public string Codigo { get; set; }
            public string Descripcion { get; set; }
            public Nullable<decimal> PrecioVenta { get; set; }
            public Nullable<decimal> Stock { get; set; }
            public System.DateTime FechaCreado { get; set; }
            public byte[] Imagen { get; set; }
            public int IdUsuario { get; set; }
        
            public virtual tblCategoria tblCategoria { get; set; }
            public virtual tblUnidad tblUnidad { get; set; }
            public virtual tblUsuario tblUsuario { get; set; }
        }

    y también la clase producto esto con el fin de cambiarle su nombre de tbl_Productos a Productos

    namespace CapaLogica
    {
        public class Producto : tblProducto
        {
            //public string PrinmerNombre { get; set; }
            //public string SegundoNombre { get; set; }
            public string Codigo { get; set; }
    
            public string Descripcion { get; set; }
            public decimal Precio { get; set; }
            public static void InsertarProducto(Producto producto)
            {
                using (GourmetEntities db = new GourmetEntities())
                { 
                    db.sp_InsertarProducto(producto.IdCategoria, producto.IdUnidadMedida, producto.Codigo, producto.Descripcion, producto.PrecioVenta, producto.Stock, producto.FechaCreado, producto.Imagen,producto.IdUsuario);
                }
            }
            
            public static object ListaProducto()
            {
                using (GourmetEntities db = new GourmetEntities())
                {
                    //id = 1;
                    //var Lista = db.Database.SqlQuery<object>("exec SPAlgunosCampos").ToList();
                    return db.SPAlgunosCampos().ToList(); //// Funciona
                    
                    //return db.tblProductoes.SqlQuery("Exec SPAlgunosCampos");
                }
                
            }
        }
    }

    esto es lo que tengo de momento, ya en el mensaje anterior le mostré como muestro en un formulario los productos cuando doy click en una categoría me muestra los productos de esa categoría, el mismo esta pensado para dar mantenimiento a los productos.

    creo que aquí debo hacer un list<Productos> no es cierto

    Gracias 

    Roberto.

    sábado, 14 de marzo de 2020 13:03
  • Hola Roberto

    De EF yo no entiendo ni "j", pero me parece que en lugar de object, ListaProductos() debería retornar un List<ALGO>.

    No entiendo por qué hereda la clase Producto de tblProducto, o sea de qué sirve tblProductos.

    Y otra cosa que no se si lo entiendo bien, la FK a la tabla Categorias tiene que ser un entero o int, no un objeto o referencia a tblCategorias (que no se lo que es).

    Como yo desconozco EF, y la verdad no tengo tiempo de ponerme a estudiarlo porque tengo que estudiar otras cosas, quizás podríamos pedirle a Leandro o a otro/a que lo conozca que te revise el código de EF, y yo te sigo ayudando con el código C#. Ah, algo que creo sabes, es que hay que separar la Capa Lógica o de Negocio, de la Capa de Presentación.

    sábado, 14 de marzo de 2020 15:44
  • Estimado Tigre. muy buen día.

    otra vez gracias por lo de la semana pasada. muchas gracias.

    ahora con relación a la ultima respuesta intento conocer EF, ahora tengo esta estructura

    dentro de la capa datos estan todas las entidades que son una clase por cada tabla que tengo en mi bd y una de esas tablas es.

    public partial class tblProducto
        {
            public int Id { get; set; }
            public int IdCategoria { get; set; }
            public int IdUnidadMedida { get; set; }
            public string Codigo { get; set; }
            public string Descripcion { get; set; }
            public Nullable<decimal> PrecioVenta { get; set; }
            public Nullable<decimal> Stock { get; set; }
            public System.DateTime FechaCreado { get; set; }
            public byte[] Imagen { get; set; }
            public int IdUsuario { get; set; }
        
            public virtual tblCategoria tblCategoria { get; set; }
            public virtual tblUnidad tblUnidad { get; set; }
            public virtual tblUsuario tblUsuario { get; set; }
        }

    y en la clase producto solo heredo, tal vez no tiene sentido pero lo hago por dos motivos una no ir a capa datos

    y la otra por mejorar el nombre de tblproductos a Productos es solo eso

    por favor si esta mal me gustaría que Ud. o alguna otra persona me den sus punto de vista ya que quiero ver hasta donde puedo avanzar esta semana.

    y con relación que me va a seguir ayudando con lo que concierne a C#, yo muy agradecido porque la verdad lo que hasta hoy me a ayudado ya es mucho para mi.

    otra vez gracias.

    buen día.

    Roberto

    lunes, 16 de marzo de 2020 13:00
  • Estimado Tigre, buen día de nuevo entonces ahí voy de nuevo.

    tengo dudas sobre este mensaje por ejemplo esta parte 

    sera que yo no estaría ya dejando fija una lista de productos. y que tal que se quiera agregar mas productos debo compilar el programa de nuevo,

    string[] codigosBebidas = new string[] {
        "sevenUp",
        "aguaMineral", 
        "cerveza",
        "cocaCola", 
        "jugoFrutas"
    };

    por favor en ningún momento quiero que se entienda por cuestiona miento, solo son dudas y tal vez no entiendo esta parte nada.y mi otra duda sería la que me comenta

    que tienen que tener el mismo orden. que pasa si el usuario cambio el nombre a una imagen y ordena alfabéticamente, que sucedería.o que tal que una imagen sea borrada ya no tendrían el mismo orden no es cierto.

    por favor Tigre una explica dita mas por favor.

    ya que la verdad no lo entiendo.

    Gracias

    Roberto

    lunes, 16 de marzo de 2020 13:19
  • Hola Roberto

    Me parece que estábamos haciendo algo mal desde antes. Cada Producto debe tener un campo único que lo indentifique, digamos, el id. Se si agregan o se borran productos, no pasa nada, porque el id es autoincremental en la base de datos. Tendrías que agregar un campo en la Tabla Producto, que sea la ruta o path de su imagen, o bien sólo el nombre del archivo si suponemos están todas en la misma carpeta. 

    Y tener una clase Producto, con todos sus atributos o propiedades, más una para el índice (que no está en la Tabla) que indique en que posición está en el List<Producto>, que los contendrá a todos en memoria para su rápido acceso, NO vas a estar haciendo una consulta a la base de datos constantemente por cada venta, sino que tendrás todos los productos "a mano" en un List<Producto>, que lo llenas haciendo al principio un SELECT a la Tabla Producto. Así, al cargar los botones dinámicos, le pones en su Tag el número de índice del Producto (índice que lo identifica dentro del List<>), y así al dar click en cualquier botón tenes el índice del Producto para poder acceder a sus propiedades en el List. Esta sería una forma fácil, aunque creo que hay otras mejores. 

    lunes, 16 de marzo de 2020 21:07
  • Como le va Tigre justamente pensaba lo mismo.

    como siempre digo(Pueda que no este bien planteado)

    tengo una consulta donde que es esta 

    public static List<tblProducto> ListProductsbyIdCategori(int id)
            {
                using (GourmetEntities db = new GourmetEntities())
                {
                    var ListproducsbyCategori = (from lt in db.tblProductoes
                                                 where lt.IdCategoria == id
                                                 select lt).ToList();
                    return ListproducsbyCategori;
                }
    
            }

    que hace esta consulta, pues le doy un id de categoría, y me trae todos los productos de esa categoría.

    ahora lo siguiente en el boton hice esto tal vez esta mal por favor ayudeme a implementarlo de la manera correcta

    private void TsbBebidas_Click(object sender, EventArgs e)
            {
    
                #region Funcional
                // Esto es para Usar el Tag
                //var btn = (ToolStripButton)sender;
                //string directorio = @btn.Tag.ToString();
                //CargarProductos(directorio);
                #endregion
                #region MyRegion
                // esto es para llamar la cantidad de productos de esa categoria y hacer el array
                CantidadBotones = (int)Producto.ListProductsbyIdCategori(1).Count();//// Funciona
                //var a = Producto.ListProductsbyIdCategori(1);
                //CantidadBotones = a.Count();
                //foreach (var item in a)
                //{
                //    IdCategoria = item.IdCategoria;
                //}
    
    
                CargarProductos(CantidadBotones);
    
                #endregion
    
            }


    por favor, es solo la región myRegion

    entonces que hace, le doy el id de la categoría y me trae los registros los cuento , y crea los botones en la cantidad de productos de esa categoría. Funciona me crea los botones.

     ahora no le mencione que desde antes opte por guardar la imagen en un campo de mi tabla producto

    ahora estimado tengo esta idea, pero no se como implementarla.

    hacer un foreach y recorrer los registros y que luego de crear los botones agregar las imágenes pero ya de la tabla, y no así de la carpeta. así no tendríamos ese problema de que se borren los registros.

    cree que es posible y también pensaba que en el button.Tag agregar el Id del producto cosa que al presionar le pase el id del Tag a la consulta. 

    private void CargarProductos(int CantBtn)
            {
    
                #region Funcional
                //int a;
                //if (botones == null)
                //    botones = new List<Button>();
                //botones.Clear();
    
    
                //string[] imagenes = Directory.GetFiles(directorio, "*.png"); //// Original Tigre
                //foreach (var imagen in imagenes)
                //{
                //    botones.Add(new Button());
                //}
                //for (a = 0; a < botones.Count; a++)
                //{
                //    botones[a].Image = new Bitmap(imagenes[a]); //Agrega la imagen al btn Tigre
                //    botones[a].Size = new Size(200, 200); //Size(106, 106);
                //    //botones[a].Name = imagenes[a].;
                //}
                ////panel1.Controls.Clear();
                ////panel1.Controls.AddRange(botones.ToArray());
                //FlpImagenProductos.Controls.Clear();
                //FlpImagenProductos.Controls.AddRange(botones.ToArray()); 
                #endregion
    
                #region PruebasBD
                //var img = Producto.ListProductsbyIdCategori(idCat);
                //int imagenes = img.Count;
                //foreach (var item in img)
                //{
                //    im = item.Imagen;
                //}
                int[] imagenes = new int[CantBtn]; //// al 5 debo reemplazar el numero de Registros que vienen de mi bd
                int a;
                if (botones == null)
                    botones = new List<Button>();
                botones.Clear();
                foreach (var imagen in imagenes)
                {
                    botones.Add(new Button());
                }
                for (a = 0; a < botones.Count; a++)
                {
                    //botones[a].Image = new Bitmap(imagenes[a]); //Agrega la imagen al btn Tigre
                    botones[a].Tag = // aquí el id del producto 
                    botones[a].Size = new Size(200, 200); //Size(106, 106);
                    //botones[a].Name = imagenes[a].;
                }
                FlpImagenProductos.Controls.Clear();
                FlpImagenProductos.Controls.AddRange(botones.ToArray());
                #endregion
    
            }

    por favor en este código no vea la región que dice funcional esa es la idea original y funciona correctamente de hecho esta muy bien pero me preocupa es justo eso si cambio el orden o elimino una imagen, mientras que si traigo de la bd no creo que pase eso.

    por favor que piensa de esto.

    gracias

    Roberto

    lunes, 16 de marzo de 2020 22:26
  • Hola Roberto

    Aparentemente y en lineas generales lo veo bien todo. Sólo destacaría algunas cosas:

    1) ¿Podrías quitar los comentarios, o sea todo el código que no sirve o ya no va más? Porque eso genera confusión visual (a mi y a vos, que leemos el código). ¿Y luego me mostras de nuevo el código? Por ejemplo vi algo como:

    int[] imagenes = new int[CantBtn];  // que no está comentado y creo que está mal y no va

    y también hay cosas que están comentadas y creo que no deberían

    2) Yo en lo personal usaría las imágenes en una carpeta para no complicar la base de datos, y en la Tabla Productos pondría el nombre de los archivos de imagen.

    lunes, 16 de marzo de 2020 23:10
  • Ok estimado, me disculpo. limpiare el código (lo envío así para que tal vez vea que no solo espero que se me de el código sino que también busco la forma de hacer personalmente, bueno sin éxito de momento pero lo intento)

    ok entonces, tengo estos código

    en el botón Click

    private void TsbBebidas_Click(object sender, EventArgs e)
            {
                #region MyRegion
                // esto es para llamar la cantidad de productos de esa categoria y hacer el array
                var btn = (ToolStripButton)sender; // esto para obtener el tag del mismo boton
                int tag = int.Parse(btn.Tag.ToString()); // aquí lo obtengo
                CantidadBotones = (int)Producto.ListProductsbyIdCategori(tag).Count(); // aquí llega el Tag es 1 el valor
                CargarProductos(CantidadBotones);
                #endregion
    
            }

    ya me crea los botones.

    ahora este codigo es el metodo para crear los botones ya es conocido

    private void CargarProductos(int CantBtn)
            {
                #region PruebasBD
                var img = Producto.ListProductsbyIdCategori(CantBtn); // Aqui llega el Id de la categoria ej. 1
                byte[] objimg;
                foreach (var item in img)
                {
                    add = (Byte[])item.Imagen; // aquí estoy recorriendo mi consulta y me obtiene la imagen
                }
    
                int[] imagenes = new int[CantBtn]; // Aquí llega el numero de registros, para crear los botones
    
                int a;
                if (botones == null)
                    botones = new List<Button>();
                botones.Clear();
                foreach (var imagen in imagenes)
                {
                    botones.Add(new Button());
                }
                for (a = 0; a < botones.Count; a++)
                {
                    //botones[a].Image = new Bitmap(imagenes[a]); //Agrega la imagen al btn Tigre
                    botones[a].Image = objimg[a]; // No funciona no puedo 
                    botones[a].Tag = // aquí el id del producto 
                    botones[a].Size = new Size(200, 200); //Size(106, 106);
                    //botones[a].Name = imagenes[a].;
                }
                FlpImagenProductos.Controls.Clear();
                FlpImagenProductos.Controls.AddRange(botones.ToArray());
                #endregion
    
            }

    Estimado el gran problema que tengo es como obtener la imagen ya no puedo mas ya intente por mis medios no puedo, por favor ayúdeme con eso por favor. ya gaste mucho tiempo y no puedo.

    2) Yo en lo personal usaría las imágenes en una carpeta para no complicar la base de datos, y en la Tabla Productos pondría el nombre de los archivos de imagen.

    ok entonces siguiendo su consejo lo hago de esta manera.

    Respondame a esto por favor. debo guardar en el campo imagen de la tabla la ruta no es cierto

    ejemplo "C:\\Recursos\Imagenes\ImagenesGourmet\PanIntegral.png"

    Gracias Tigre. 

    Aguardo 

    Gracias

    Roberto

    lunes, 16 de marzo de 2020 23:38
  • Hola Roberto

    Trato de ir en orden:

    El método del evento Click de los ToolStripButton puede ser uno solo para todos, ya que cada uno tiene su diferente Tag y cada cual traerá los botones de los productos de su propia Categoría. A propósito, y en general, te pido si podrías ser más preciso con los nombres de las variables, o sea que coincida su nombre con lo que es (te pido, para evitar la ensalada rusa en mi cabeza). 

    El 1er código ...

    Pasas el Tag a número, se supone que le pones el id ... OK

    Calculas la cantidad de productos de la Categoría ... OK

    Invocas a CargarProductos() pasándole la cantidad de productos? ... Hmmm 

    No deberías pasarle el id?

    El 2do código ...

    No entiendo muy bien lo de EF pero parece que confundis Cantidad de Botones con el id ... Hmmm

    Con lo cual img entiendo que estará vacío (porque cantidad de botones será mucho más que 1)

    En el foreach () asignas siempre a 'add' que no se qué es ni dónde lo declaras ... Hmmm

    En lugar de esto:

    int[] imagenes = new int[CantBtn]; // Aquí llega el numero de registros, para crear los botones
    
                int a;
                if (botones == null)
                    botones = new List<Button>();
                botones.Clear();
                foreach (var imagen in imagenes)
                {
                    botones.Add(new Button());
                }
                for (a = 0; a < botones.Count; a++)
                {
                    //botones[a].Image = new Bitmap(imagenes[a]); //Agrega la imagen al btn Tigre
                    botones[a].Image = objimg[a]; // No funciona no puedo 
                    botones[a].Tag = // aquí el id del producto 
                    botones[a].Size = new Size(200, 200); //Size(106, 106);
                    //botones[a].Name = imagenes[a].;
                }
                FlpImagenProductos.Controls.Clear();
                FlpImagenProductos.Controls.AddRange(botones.ToArray());


    Por qué no algo como esto:

    int a; if (botones == null) botones = new List<Button>(); botones.Clear(); for (a = 0; a < CantBtn; a++) { botones.Add(new Button()); //botones[a].Image = new Bitmap(imagenes[a]); //Agrega la imagen al btn Tigre botones[a].Image = objimg[a]; // No funciona no puedo botones[a].Tag = // aquí el id del producto botones[a].Size = new Size(200, 200); //Size(106, 106); //botones[a].Name = imagenes[a].; } FlpImagenProductos.Controls.Clear();

    FlpImagenProductos.Controls.AddRange(botones.ToArray());

    Quizás para cargar en objimg las imágenes lo que quisiste hacer era:

    List<byte[]> objimg = new List<byte[]>();
    
    foreach (var item in img)
        objimg.Add((Byte[])item.Imagen);

    Para tener en un List<> las imágenes? 

    Si hay algo de sintaxis o de concepto que no sabes como es o como se escribe, podes explicármelo así te lo explico.

    Si, podes guardar la ruta completa de las imágenes, o podes guardar sólo el nombre de cada imagen, total la ruta de directorio es siempre la misma, y que sea así igual para todos los usuarios de tu sistema, que sea por ejemplo "imagenes", en la misma ubicación que el .EXE, así que vos ponela en la carpeta "Debug".

     



    martes, 17 de marzo de 2020 0:29
  • Estimado Tigre.

    buenas noches esta parte no la entiendo la verdad 

    List<byte[]> objimg = new List<byte[]>();
    
    foreach (var item in img)
        objimg.Add((Byte[])item.Imagen);

    la parte 

    in img no se que parte fue declarado

    ese foreach no tiene los corchetes.

    que tenga buenas noches.

    ya mañana seguimos 

    Gracias

    Roberto

    martes, 17 de marzo de 2020 2:49
  • Estimado Tigre buen día. ahora entonces entiendo esto

     var img = Producto.ListProductsbyIdCategori(IdCategoria); // Aqui llega el Id de la categoria ej. 1
                List<byte[]> objimg = new List<byte[]>();
    
                foreach (var item in img)
                {
                    objimg.Add((Byte[])item.Imagen); // Aquí capturo el atributo imagen o el campo imagen
                }
      
    me dice esto

    ahora hice esto mas

     var img = Producto.ListProductsbyIdCategori(IdCategoria); // Aqui llega el Id de la categoria ej. 1
                List<byte[]> objimg = new List<byte[]>();
                Bitmap imagen = null;
                foreach (var item in img)
                {
                    objimg.Add((Byte[])item.Imagen);
    
                   
    
                    Byte[] bytes = (Byte[])(item.Imagen);
    
                    MemoryStream ms = new MemoryStream(bytes);
    
                    imagen = new Bitmap(ms);
    
                    //return imagen;
                }
      

    me carga la imagen pero son dos botones y en los dos me carga la misma es claro que no hay el bucle [a]

    porque cuando le pongo los corchetes me dice este mensaje

    al menos ya conseguí que se cargue la imagen.

    por favor estimado en que estoy fallando.

    ojala no sea en todo.

    Gracias 

    Roberto

    martes, 17 de marzo de 2020 14:47
  • Hola Roberto

    En el último código que mostras le asignas el el new Bitmap() a la misma variable, no se que haces después pero es probable que si asignas ESA imagen sea la misma en los botones.

    Lo que tendrías que hacer es poner TODO (incluido lo de la imagen) en el mismo bucle donde haces lo de los botones. Lo de img y como lo cargas con EF tendrías que dejarlo para así en lo siguiente podes leer las imágenes.

    Byte[] bytes;
    MemoryStream ms;
    for (a = 0; a < CantidadBotones; a++)
    {
        botones.Add(new Button());
    
        bytes = (byte[])img[a].Imagen;
    
        ms = new MemoryStream(bytes);
    
        botones[a].Image = new Bitmap(ms);
    
        botones[a].Tag = a; // o no se que pones aquí
    
        botones[a].Size = new Size(200, 200); // o quizás menos??
    }
    Aunque yo haría las cosas diferente. Haría una clase Producto con todos sus atributos, incluido su índice en el List<Producto>, incluida su imagen, etc., y así establecer los botones y todo sería más fácil.


    martes, 17 de marzo de 2020 18:58
  • Estimado Tigre le paso una imagen para que vea que sí funciono.

    Gracias hasta aquí.

    ahora estimado en el .Tag habia pensando en ponerle el Id del producto.

    y de donde tomo el Id del producto

    la idea mía es que al cargar la imagen también se cargue en el tag el Id del producto.

    y luego con una consulta yo consigo los demás datos y pasarlos al listview, pero de momento me gustaria mostrarlo en un messagebox para probar primeramente. ahora también intento colocarle un nombre al button

    quiero probar si los datos son los correctos por eso quiero hacer esa prueba estimado.

    por favor como hago click a un boton creado dinamicamente, lo investigare pero por favor si me puede ayudar.

    Gracias

    Roberto

    martes, 17 de marzo de 2020 21:25
  • Estimado Tigre. he hecho esto mas para llegar a lo que quería, que era ver en un messagebox el valor del Tag y la verdad funciona.

    Porque se lo paso, pues porque quiero que por favor me diga si es correcta la manera o si podemos hacer de una manera mas optima para así no usar mucho recurso.

    este es el handler

    private void handlerComun_Click(object sender, EventArgs e)
            {
                Button clickedButton = (Button)sender;
                //clickedButton.Text = "Botón Click";
                MessageBox.Show(clickedButton.Tag.ToString());
            }

    aquí lo consumo

    botones[a].Click += new EventHandler(handlerComun_Click);

    y el resultado es este

    eso me muestra que está correcto el valor del TAG

    Seguiré, mientras me da su visto a como voy yendo.

    Gracias

    Roberto

    martes, 17 de marzo de 2020 22:43
  • Hola Roberto

    Como te venía diciendo, me parece que la mejor práctica, además de lo más sencillo de realizar, es definir una clase Producto, que contenga todos los atributos del mismo, más el índice (que contendrá el índice propio del List<Producto> donde irá alojado). Y al arrancar la aplicación, cargas TODOS los productos en ese List. Luego, al hacer click en un ToolStripButton de Categoría, le pasas el índice (el miembro de la clase Producto, que lo identifica en el List) de cada uno de los productos de la Categoría seleccionada, al Tag del Button, y así luego al dar click en alguno de ellos lo podrás identificar por el índice (que lo volves a pasar a int) en el List<Producto> principal y así podrás acceder a todos sus atributos.

    ¿ Cómo logras cargar todos los productos en un List<Producto> ?

    Primero definis la clase Producto

    class Producto {
    
        public Producto(int Id, string Codigo, int CategoriaId, string Descripcion, float PrecioVenta, float PrecioCosto, int Indice)
        {
            this.Id = Id;
            this.Codigo = Codigo;
            this.CategoriaId = CategoriaId;
            this.Descripcion = Descripcion;
            this.PrecioVenta = PrecioVenta;
            this.PrecioCosto = PrecioCosto;
            this.Indice = Indice;
        }
    
        public int Id { get; set; }
        public string Codigo { get; set; }
        public int CategoriaId { get; set; }
        public string Descripcion { get; set; }
        public float PrecioVenta { get; set; }
        public float PrecioCosto { get; set; }    
        public int Indice { get; set; }     
    }

    Y luego, luego de crear el

    List<Producto> productos = new List<Producto>();

    lo cargas con todos los productos, que no se como harás para traerlos con EF, pero (si no me equivoco acerca de EF) los traes primero con EF a una Entity o como se llame, y luego le pasas todos los atributos, en un bucle for, a los objetos de la clase Producto, más (importante recordar) el índice, que simplemente es el contador del for, que servirá, como te expliqué antes, para identificar al producto cuando esté "perdido" en su grupo de botones. 

    Por favor, estimado Roberto, te pido que intentes "digerir" esto bien, porque si bien ya has conseguido resolver unas cuantas cosas, creo que esto es de lo más importante. O sea, por ejemplo, si tenes el índice del producto, y tenes el List<> de Producto, tenes la info de todos los productos. Otra cosa a mencionar, que cada vez que agregas, o si eliminas, un producto, allí se tiene que volver a cargar el List<>, o sea, actualizarlo. 

    Y para obtener los Producto de una determinada Categoría, simplemente, haces otro List<>, y filtras por el miembro CategoriaId los que coincidan con el Id de la Categoría seleccionada. Allí tendrás, entre otros, la imagen para asignarle al Button, el índice se lo pones en el Tag, etc..

    Más tarde, o mañana, te paso el código, si hace falta. Pero por favor, fijate si vas "procesando" esto, y quizás podes escribir vos mismo el código.

    miércoles, 18 de marzo de 2020 1:10
  • Estimado buen día.

    y de verdad que me esta costando digerir esta parte pero le comento lo siguiente.

    por lo que he leido de EF cada tabla de la base de datos se convierte en una clase.

    entonces tengo mi tabla producto que la denomino tblProducto y este es el codigo.

    CREATE TABLE [dbo].[tblProducto](
    	[Id] [int] IDENTITY(1,1) NOT NULL,
    	[IdCategoria] [int] NOT NULL,
    	[IdUnidadMedida] [int] NOT NULL,
    	[Codigo] [varchar](200) NOT NULL,
    	[Descripcion] [varchar](500) NOT NULL,
    	[PrecioVenta][money] NULL,
    	[Stock][decimal](8,2) NULL,
    	[FechaCreado] [datetime] NOT NULL,
    	[NombreImagen] [varchar](100) NOT NULL,
    	[Imagen] [image] NULL,
    	[IdUsuario][int] not null,
    	CONSTRAINT [PK_tblProducto] PRIMARY KEY CLUSTERED (Id),
    	CONSTRAINT [FK_tblUnidad] FOREIGN KEY (IdUnidadMedida) REFERENCES tblUnidad(Id),
    	CONSTRAINT [FK_tblUsuario] FOREIGN KEY (IdUsuario) REFERENCES tblUsuario(Id),
    	CONSTRAINT [FK_tblCategoria] FOREIGN KEY (IdCategoria) REFERENCES tblCategoria(Id)
    	);

    y en C# tengo ya la clase con los mismos campos que es esta clase

     public partial class tblProducto
        {
            public int Id { get; set; }
            public int IdCategoria { get; set; }
            public int IdUnidadMedida { get; set; }
            public string Codigo { get; set; }
            public string Descripcion { get; set; }
            public Nullable<decimal> PrecioVenta { get; set; }
            public Nullable<decimal> Stock { get; set; }
            public System.DateTime FechaCreado { get; set; }
            public string NombreImagen { get; set; }
            public byte[] Imagen { get; set; }
            public int IdUsuario { get; set; }
        
            public virtual tblCategoria tblCategoria { get; set; } // Llave foranea
            public virtual tblUnidad tblUnidad { get; set; } // Llave foranea
            public virtual tblUsuario tblUsuario { get; set; } // Llave foranea
        }

    yo necesito unos campos mas, para ello y aprovechando la herencia cree una clase llamada producto 

    que es esta

    public class Producto : tblProducto
        {
            public int Cantidad { get; set; }
            public string NombreCortoMedida { get; set; } // Ej. Un , Lt , Kg 
            public decimal SubTotalFila { get  {return Cantidad * (decimal)PrecioVenta; } }
    		
    		public static List<tblProducto> Lista_Una_Venta(int id)
            {
                using (GourmetEntities db = new GourmetEntities())
                {
                    var ListproducsbyCategori = (from lt in db.tblProductoes
                                                 where lt.IdCategoria == id
                                                 select lt).ToList();
                    return ListproducsbyCategori;
                }
    
            }
    	}

    Pero ahora veo que Ud. creo un constructor de la clase producto y agrego algunos campos mas, ahora la clase derivada está de esta manera.

    public Producto(int Id, string Codigo, int IdCategoria, string Descripcion, decimal PrecioVenta, float PrecioCosto, int Indice)
            {
                this.Id = Id;
                this.Codigo = Codigo;
                this.IdCategoria = IdCategoria;
                this.Descripcion = Descripcion;
                this.PrecioVenta = PrecioVenta;
                this.PrecioCosto = PrecioCosto; // Este campo no esta en la tabla
                this.Indice = Indice; // Este Campo no esta en la tabla
            }

    El atributo Indice no esta en la tabla, esto es nuevo para mi la verdad no se como va a trabajar ese indice, pero ahí vamos de ida.

    ahora como me dice que al momento de cargar la aplicación y abrir el formulario debo cargar los productos hice esto en el Load del formulario

    private void FrmPanelPrincipalProductos_Load(object sender, EventArgs e)
            {
                List<Producto> productos = new List<Producto>();
                productos.Add();
            }

    pero ya mis conocimientos llegan hasta aquí.

    por favor si me puede ayudar con esto mas.

    Gracias Tigre.

    Roberto

    miércoles, 18 de marzo de 2020 14:23
  • Hola Roberto

    El atributo Indice de la clase Producto no está en la tabla, pero lo necesitas para saber cual es el Producto cuyo botón se ha clickeado. Nada más ni nada menos que para eso. El índice te dice cual objeto del List<Producto> es el que seleccionaste de los botones dinámicos (para ir agregándolos a la lista de la venta), porque si le pasas el Id, tendrías que realizar otra búsqueda que implicaría más código (y más complicación, o bien un método BuscarPorId()). O sea, en todo momento en la aplicación se debe tener en memoria, en un List<Producto>, todos los productos, es decir, la información de los mismos, para poder anotarlos en la lista de venta.

    Lo que te pido es que leas bien mi respuesta anterior, y luego esta, y me digas si algo no está bien claro. Así podemos avanzar.

    Algo que vi por ahí que me parece mal, es agregar a la clase Producto el "SubTotalFila", eso se anota directamente en el ListView o el control que sea que uses para hacer el cálculo de la venta, a su debido momento. Que me gustaría que lo veamos un poquito más adelante, cuando tengamos bien lo principal del programa, que es el List<Producto> y los botones dinámicos y la selección de productos para ir agregándolos en la lista de venta, de a uno. 

    Te paso el código del handlerComun(), según me parece a mi. 

    private void handlerComun(object sender, EventArgs e) { Button clickedButton = (Button)sender; int indice = Convert.ToInt32(clickedButton.Tag); // aquí tenes el índice que te dice cual es el Producto seleccionado en su List<Producto> listViewVenta.Items.Add(productos[indice]); // esto es un supuesto pero ilustra bien como usar el miembro de clase Indice, // que se lo pasas al Tag del Button como string y acá lo recuperas como int, // y accedes con el índice al List<Producto> para usar ese producto, con todos

    // sus atributos como quieras

    }

    El precio de costo tampoco está en la tabla, pero supongo que lo necesitarás cuando hagas las compras de mercadería y así llevar una mini contabilidad del negocio, o sea, cuánto gastas y cuánto vendes.

    Por favor lee bien todo.

    Saludos



    miércoles, 18 de marzo de 2020 19:15
  • Estimado Tigre buenas noches.

    La verdad me esta costando digerir esta parte, pero lo entenderé.

    estoy eliminando la el atributo SubTotal y voy a agregar a la tabla el precio de compra.

    ahora una pregunta mas como capturo el indice para agregarlo al Tag del botón por favor para probar si realmente voy bien.


    listViewVenta.Items.Add(productos[indice]); // aquí donde dice [indice] es lo que debo obtener del Tag no es cierto.

    me gustaría hacer una prueba mostrando en un messagebox los datos para ver si son capturados.

    esta prueba que quiero hacer es para saber si estoy trayendo los datos desde la Bd porque la verdad no lo entiendo mucho este procedimiento

    osea lo que no es es que si con lo que ya tengo voy bien o no voy bien. por favor si me va corrigiendo.

    por favor ayúdeme.

    muchas gracias Tigre

    Roberto

    jueves, 19 de marzo de 2020 0:27
  • Buenas noches Roberto

    El precio de compra lo tendrías que agregar solamente si vas a usarlo para hacer un resumen de gastos, o si vas a hacer un resultado entre ganancia y pérdida, o sea una pequeña contabilidad, si no, no es necesario. Yo creía (ahora no se) que ibas a ingresar los productos al sistema como una "compra de mercadería". O quizás lo que haces es comprar por varias unidades distintos artículos y luego armas los productos finales de venta. Eso tendrías que pensarlo vos como será, si es que será algo.

    El índice (miembro de la clase Producto) lo obtenes cuando cargas los productos, por ejemplo: Supone que con EF cargas los atributos, pero sólo los de la tabla, en un List<tblProducto> lista. Luego haces esto:

    int a;
    List<Producto> productos = new List<Producto>();
    for (a = 0; a < lista.Count; a++) 
    {
        productos.Add(lista[a].Id, lista[a].Codigo, lista[a].CategoriaId, lista[a].Descripcion, lista[a].PrecioVenta, lista[a].PrecioCosto, lista[a].Stock, a);
    }
    

    El último parámetro que le pasas es el propio índice de cada objeto en la lista, que sirve para identificarlo en esa misma lista, llamada productos. La otra, lista, es lo que obtuviste de EF, que no tengo idea de como es. Por eso te decía, que es mucho más fácil y sencillo usar lenguaje T-SQL y SqlCommand.

    Con respecto a si venimos bien o mal, me parece que ahora que empieces a hacer lo del List de productos, ahí vamos a comenzar a darle forma, lo que rescataría por ahora es lo de los botones dinámicos y el Tag, y lo que tengas bien hecho de EF que no lo se. 

    Saludos

    jueves, 19 de marzo de 2020 1:44
  • Estimado Tigre en cuanto haga eso que me indica regreso, ya que estoy confundido de momento pero no me voy a quedar sin conseguirlo. 

    referente a de que se trata la aplicacion me gustaria poderla implementar en una panaderia donde venden diferentes tipos de panes, masas y otros. y tambien bebidas.

    tambien tendre una tabla donde ingrese todo los insumos que compro para fabricar los panes 

    Harina, Aceite, Sal, Levaduras y otros.

    gracias estoy trabajando en lo que me dice tengo este codigo que esta en T-SQL, pero lo llevare a EF.

    Es muy comun que cuando estamos realizando algun programa escolar o un proyecto, necesitamos utilizar estructuras de datos y visualizarlas. Pues bien, les dire como cargar informacion desde una base de datos a una lista manipulable 100% y despues visualizarla en un DataGridView, todo escrito en C# y SQL Server 2005.
    
    Debemos tener creada la Base de Datos con la tabla que queremos cargar en nuestro List, posteriormente debemos crear una Clase que contenga los mismos campos de la tabla como atributos:
    Ejemplo:
    
    Crearemos una clase llamada Empleados.cs
    
    
    public class Empleados
        {
            private string _no_empleado;
            private string _paterno;
            private string _materno;
            private string _nombre;
    
            public string NoEmpleado
            {
                get { return _no_empleado; }
                set { _no_empleado = value; }
            }
            public string Paterno
            {
                get { return _paterno; }
                set { _paterno = value; }                                    
            }
            public string Materno
            {
                get { return _materno; }
                set { _materno = value; }
            }
            public string Nombre
            {
                get { return _nombre; }
                set { _nombre = value; }
            }
            public SearchFunction(string NoEmp, string paterno, string materno, string nombre)
            {
                this.NoEmpleado = NoEmp;
                this.Paterno = paterno;
                this.Materno = materno;
                this.Nombre = nombre;
            }             
        }
    
    Ya teniendo declarada la clase, para crear una lista de Empleados, debemos declarar un List de tipo Empleados para cargarlos desde la BD:
    
    List<Empleados> objEmpleados = new List<Empleados>();
    SqlConnection miConexion = new SqlConnection("Server=(local)\\SQLEXPRESS;database=MiDataBase;integrated security=yes");
    
    string query = "SELECT Id, Paterno, Materno, Nombre FROM Empleados";
                try
                {
                    using (SqlCommand cmd = new SqlCommand(query,miConexion))
                    {
                        SqlDataReader dr;
                        cmd.Connection = miConexion;
                        cmd.Connection.Open();
                        dr = cmd.ExecuteReader();
                        if (dr.HasRows == true)
                            while (dr.Read())
                                objEmpleados.Add(new SearchFunction(dr[0].ToString(), dr[1].ToString(), dr[2].ToString(), dr[3].ToString()));
                        cmd.Connection.Close();
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }

    Gracias Tigre.

    Roberto

    jueves, 19 de marzo de 2020 20:08
  • Estimado Tigre. buenas noches.

    la verdad no he podido hacer de esta forma no consigo cargar una lista con datos de una tabla.

    y la ayuda que tengo es con T-SQL.

    abra otra forma de hacer esto por favor. y ya luego estoy seguro que podremos hacer de esa manera.

    espero sus comentarios. al respecto.

    Gracias 

    Roberto

    viernes, 20 de marzo de 2020 0:40
  • Buenas noches, Estimado Roberto

    No entiendo bien el planteo, ahora, o sea cuál sería la pregunta? (Disculpá). 

    Recién respondí tu otra pregunta, no se si lo viste.

    viernes, 20 de marzo de 2020 1:11
  • Estimado Tigre.

    Buenas noches. que todo este bien.

    Estimado ya tengo resuelto esta parte la verdad no pude traer la tabla a la lista, pero lo hice de otra forma, mientras tanto. así me esta quedando. 

    Lo que ahora me trae a molestarlo es por sus sugerencia.

    ya tengo esto como ve en la imagen, como debo hacer de aquí para adelante, el cliente pidió todo eso (Mucho verdad?), es un ejemplo ahora, la idea mía es que al presionar el botón procesar venta me salga el encabezado porque lo pretendo guardar en un maestro detalle lo que vemos ahora es el detalle.

    o me puede por favor apoyar con alguna idea de como sería mejor, esta parte sería el mecanismo antes de guardar.

    que campos del producto son realmente necesarios guardar.

    yo pensaba guardar el Id, tal vez el Id de la Unidad por si en algún momento cambia, el valorventa y el precio. porque tal vez también en algún momento cambie.

    Gracias Tigre.

    Roberto

    domingo, 22 de marzo de 2020 22:47
  • Buenas noches, Roberto

    Decis, que campos guardar para registrar la venta? Yo diría que el Id, la Descripción, el Precio, y la cantidad de Unidades vendidas, así podes guardar cuánto dinero ingresó, y cosas como el Precio y el Id que pueden, o bien variar o bien desaparecer, no se verían afectados por los cambios de haberlos. 

    No se si entendí bien, decis también que aún no pudiste cargar los Productos en el List<Producto> ? Me pasas la estructura de la tabla Producto? Creo que la se bien, pero por las dudas ... Así te paso el código.

    domingo, 22 de marzo de 2020 23:54
  • Estimado Tigre. mil disculpas por responder recién mil disculpa 

    esta es la tabla

    CREATE TABLE [dbo].[tblProducto](
    	[Id] [int] IDENTITY(1,1) NOT NULL,
    	[IdCategoria] [int] NOT NULL,
    	[IdUnidadMedida] [int] NOT NULL,
    	[Codigo] [varchar](200) NOT NULL,
    	[Descripcion] [varchar](500) NOT NULL,
    	[PrecioVenta][money] NULL,
    	[Stock][decimal](8,2) NULL,
    	[FechaCreado] [datetime] NOT NULL,
    	[NombreImagen] [varchar](100) NOT NULL,
    	[Imagen] [image] NULL,
    	[IdUsuario][int] not null,
    	CONSTRAINT [PK_tblProducto] PRIMARY KEY CLUSTERED (Id),
    	CONSTRAINT [FK_tblUnidad] FOREIGN KEY (IdUnidadMedida) REFERENCES tblUnidad(Id),
    	CONSTRAINT [FK_tblUsuario] FOREIGN KEY (IdUsuario) REFERENCES tblUsuario(Id),
    	CONSTRAINT [FK_tblCategoria] FOREIGN KEY (IdCategoria) REFERENCES tblCategoria(Id)
    	);
    
    
    GO


    esta la entidad o la clase

     public partial class tblProducto
        {
            public int Id { get; set; } // 1
            public int IdCategoria { get; set; } //2
            public int IdUnidadMedida { get; set; } //3
            public string Codigo { get; set; } // 4
            public string Descripcion { get; set; } //5
            public Nullable<decimal> PrecioVenta { get; set; } //6
            public Nullable<decimal> Stock { get; set; } //7
            public System.DateTime FechaCreado { get; set; } // 8
            public string NombreImagen { get; set; } // 9
            public byte[] Imagen { get; set; } //10
            public int IdUsuario { get; set; } // 11
        
            public virtual tblCategoria tblCategoria { get; set; } // 12
            public virtual tblUnidad tblUnidad { get; set; } // 13
            public virtual tblUsuario tblUsuario { get; set; } //14
        }


    esta es la clase producto, que esta en la capa lógica, con algunos campos mas

    public class Producto : tblProducto
        {
            public string NombreCortoMedida { get; set; } // Un. Lt. Kg.
            public int Indice { get; set; }
            public Producto()
            {
    
            }
            public Producto(int Id, string Codigo, int IdCategoria, string Descripcion, decimal PrecioVenta,  int Indice)
            {
                this.Id = Id;
                this.Codigo = Codigo;
                this.IdCategoria = IdCategoria;
                this.Descripcion = Descripcion;
                this.PrecioVenta = PrecioVenta;
                this.PrecioCosto = PrecioCosto; // Este campo no esta en la tabla
                this.Indice = Indice; // Este Campo no esta en la tabla
            }
    	}

    Estimado como le decía, no pude traer a una lista mis productos, pero lo hice de otra manera y mi clase detalleVenta tiene estas campos que serán guardados en la tabla tblDetalleVenta.

     public class DetalleVenta
        {
            public int IdProducto { get; set; } // 0 Se guarda en la BD
            public string Codigo { get; set; } // 1 
            public string Descripcion { get; set; } // 2
            public decimal PrecioVenta { get; set; } // 3 Se guarda en la BD
            public string Unidad { get; set; } // 4 
            public int Cantidad { get; set; } // 5 Se guarda en la BD
            public decimal TotalFila { get { return PrecioVenta * (decimal)Cantidad; } } // 6 Se guarda en la BD
        }
    Este es el metodo para opnter los productos desde la Bd
    public static List<Producto> GetProductos()
            {
          
    
                using (GourmetEntities db = new GourmetEntities())
                {
                    var Listproducs = (from fila in db.tblProductoes
                                       join Id in db.tblUnidads on fila.IdUnidadMedida equals Id.Id
                                       select new Producto
                                       {
                                           Id = fila.Id,
                                           Codigo = fila.Codigo,
                                           Descripcion = fila.Descripcion,
                                           PrecioVenta = fila.PrecioVenta,
                                           NombreCortoMedida = fila.tblUnidad.NombreCorto
                                       }).ToList();
                                       
                                      
                    return Listproducs.ToList();
                }
    
            }

    Este mi Boton Comun que se presiona desde mis botones que se crean dinámicamente. 

    funciona todo perfectamente, pero pueda que no sea la mejor manera.

    private void handlerComun_Click(object sender, EventArgs e)
            {
                Button clickedButton = (Button)sender;
                // Abro el formulario para ingresar la cantidad
                FrmCantidad frmCantidad = new FrmCantidad();
                AddOwnedForm(frmCantidad);
                frmCantidad.ShowDialog();
    
                
                //clickedButton.Text = "Botón Click";
                int idProducto = int.Parse(clickedButton.Tag.ToString());
                //MessageBox.Show(idBotonClick.ToString());
                var producto = from productoRow in Producto.GetProductos().ToList()
                               where productoRow.Id == idProducto
                               select productoRow;
                DetalleVenta detalleVenta = new DetalleVenta();
                foreach (var item in producto)
                {
                    CultureInfo myCI = new CultureInfo("en-US", false);
                    detalleVenta.IdProducto = item.Id; // 1
                    detalleVenta.Codigo = item.Codigo; // 2
                    detalleVenta.Descripcion = item.Descripcion; // 3
                    detalleVenta.PrecioVenta = Convert.ToDecimal(item.PrecioVenta); // 4
                    detalleVenta.Unidad = item.NombreCortoMedida; // 5
                    detalleVenta.Cantidad = int.Parse(Cantidad);
                    detalleVentas.Add(detalleVenta);
                    dataGridView1.DataSource = null;
                    dataGridView1.DataSource = detalleVentas;
                    SumarTotales();
                }
            }

    en la siguiente imagen muestro como va quedando, lo funcional tal vez falta tema de visualización iconos y demás pero eso lo pienso hacer mas enseguida. ya que después, así como también validaciones y control de errores.

    todas sus sugerencias las agradeceré

    Roberto

    lunes, 23 de marzo de 2020 18:49
  • Buenas noches Roberto,

    Veo que lo hiciste a tu manera, y no está mal (por lo que se ve), aunque yo lo habría hecho de otra forma.

    Lo que si te recomiendo, es que antes de venderlo el programa, lo pruebes muy bien, a lo Q.A., o sea que tenes que intentar encontrar errores, tirar a matar, por qué? Porque es preferible que te salten a vos los errores y no al cliente.

    Dos cosas que mencionaría, que el campo o miembro Stock, no se para qué lo haces decimal, será quizás para poder marcar un kilo y medio de algo? Y que en la clase DetalleVenta hay demasiados miembros, quizás algunos innecesarios ... o quizás no.

    No se qué sugerencias darte, si tenes preguntas específicas, escribilas con número ( 1), etc. ), así no se me escapa ninguna.

    Saludos

    lunes, 23 de marzo de 2020 23:38
  • Estimado gracias.

    ok entonces hare preguntas claves ahora estoy trabajando un poco en como se vera el formulario principal que es el de ventas, bueno para mi es ese

    con relacion al stock lo que pasa que pienso hacer que al precionar el boton solo se me agregue la fila si hay cantidad suficiente para vender osea supongamos que tengo 10 panes pero el cliente me pide 20 ya no daría para vender ese producto. pienso mostrar un mensaje que diga el pedido excede a la cantidad en stock o algo por el estilo/

    ok cambiare el tipo de dato de stock a int.

    ya le doy noticias

    Gracias

    Buenas noches.

    lunes, 23 de marzo de 2020 23:52
  • Estimado Tigre buenas tardes Dios quiera que todo este bien.

    estoy avanzando estos días despacio pero voy avanzando tengo este error.

    lo que pasa que quiero que al seleccionar una fila en un ListView me muestre la imagen, aproposito he puesto en null el campo imagen de algunos productos, cuando selecciono una fila que tiene imagen muestra perfectamente, pero cuando selecciono una fila que no tiene la imagen me muestra este error lo quise poner en un if pero no entra al If siendo que que el bitmap es null muestro la imagen

    he intentado convertir el bitmap a string, a byte[] pero sin exito. 

    que mas puedo hacer estimado, aclaro que el campo en la tabla es null osea ese producto no tiene imagen o tiene imagen null

     private void TsbModificar_Click(object sender, EventArgs e)
            {
                producto.Codigo = "MOD-0011";
                producto.Descripcion = "MODIFICADO";
                producto.FechaCreado = DateTime.Now;
                producto.IdCategoria = 3;
                producto.IdUnidadMedida = 1;
                producto.IdUsuario = 1;
                producto.NombreImagen = "nombre modificado";
                producto.Imagen = null;
                producto.PrecioVenta = 100;
                producto.Stock = 20;
                producto.Activo = false;
                producto.Id = 11;
                Producto.ModificarProducto(producto, producto.Id);
            }

    el campo es image, pero como lo recuerda cambie de guardar la imagen a guardar la dirección ejemplo 

    C:\\IMAGENES\PAN.PNG

    Gracias por ayudarme

    Roberto

    jueves, 26 de marzo de 2020 19:28
  • Hola Roberto

    Me parece que el problema es que el parámetro ms que le pasas al Bitmap() ya es null, por eso te salta System.ArgumentException: El parámetro no es válido. O sea antes de que el Bitmap sea null ya es null el valor de ms y no podes usarlo. Podrías quizás preguntar con el if si ms es válido, en lugar de bitmap.

    Saludos

    Pablo

    viernes, 27 de marzo de 2020 17:40
  • Si. ya hice eso y muchas otras formas.bueno pero ya es mejor no dejar que el campo quede en nulo.

    Voy avanzando.

    Roberto

    viernes, 27 de marzo de 2020 18:25
  • Estimado Tigre buenas tardes.

    hice esto, primero converti a varbinary la imagen y su longitud me da 17 todos los null porque? la verdad no se porque su longitud es 17 hice esto

    SELECT LEN(CAST( Imagen AS varbinary)) from tblProducto  WHERE ID = 1
    
    SELECT LEN(CAST( Imagen AS varbinary)) from tblProducto  WHERE LEN(CAST(Imagen AS varbinary)) = 17
    SELECT ID from tblProducto  WHERE LEN(CAST(Imagen AS varbinary)) = 17

    entonces como todas los registros donde el campo imagen tiene null mide Len = 17 hice esto en C#

    using (GourmetEntities db = new GourmetEntities())
                {
                    var Oimagen = db.tblProductoes.Find(Id);
                    MemoryStream ms = new MemoryStream(Oimagen.Imagen);
                    if (Oimagen.Imagen.Length == 17)
                    {
                        pictureBox1.Tag = @"C:\ProductosGourmet\Pan\NoFoto.png";
                        pictureBox1.Image = Image.FromFile(pictureBox1.Tag.ToString());
                    }
                    
    
                    else
                    {
                        Bitmap bitmap = new Bitmap(ms);
                        pictureBox1.Image = bitmap;
                    }
                }

    Y efectivamente entro al If. y me cargo en el pictureBox una imagen de NoPhoto,

    gracias Tigre

    Roberto

    viernes, 27 de marzo de 2020 19:26
  • Pero no es una buena práctica eso Roberto
    viernes, 27 de marzo de 2020 20:37
  • me temía eso.

    tiene algún ejemplo de como hacerlo estimado por favor.

    Gracias

    Roberto

    viernes, 27 de marzo de 2020 20:46
  • if (ms == null) 
    {
        pictureBox1.Image = Image.FromFile(@"C:\ProductosGourmet\Pan\NoFoto.png");
    }
    else
    {
        pictureBox1.Image = new Bitmap(ms);
    }


    viernes, 27 de marzo de 2020 22:19
  • Bien estimado. pero creo que en campo image de sql no se guarda un null sino otra cosa. que ya lo averiguo aunque le paso null no llega null llega otra cosa bueno es lo que veo porque de ser así pasaría al if, porque eso ya hice.

    ahora estimado tengo este query para mi venta

    mi maestro detalle

    estos mis querys

    CREATE TABLE tblMaestroVenta
    (
    Id int identity(1,1) NOT NULL,
    NumeroVenta varchar(200) NOT NULL,
    FechaVenta datetime not null,
    IdCliente int,
    ValorVenta decimal not null,
    CONSTRAINT PK_MaestroVenta PRIMARY KEY (Id),
    CONSTRAINT FK_tblMaestroVenta_tblCliente FOREIGN KEY (IdCliente) references tblCliente(Id)
    );
    
    el detalle
    public int IdProducto { get; set; } // 0 Se guarda en la BD
            public string Codigo { get; set; } // 1 
            public string Descripcion { get; set; } // 2
            public decimal PrecioVenta { get; set; } // 3 Se guarda en la BD
            public string Unidad { get; set; } // 4 
            public int Cantidad { get; set; } // 5 Se guarda en la BD
            public decimal TotalFila { get { return PrecioVenta * (decimal)Cantidad; } } // 6 Se guarda en la BD

    el detalle aun no hice el query pero ya lo haré, tengo estas preguntas.

    1.- Que piensa de esto, quiero que el numero de venta sea el id del maestroventa por ejemplo

    mi primer venta seria el 1 yo estoy pensando ponerle Ven# 1 que implicaría que en cada venta que haga ir a la bd extraer el max de id y aumentar en 1, o de que otra forma se puede hacer. por favor.

    2.- que piensa de los campos de mi maestroVenta, son los suficientes me falta alguno mas.

    3.- en mi detalle me gustaria guardar el id del producto nada mas, ya que con solo el

    Id.

    PrecioVenta

    cantidad

    ValorVenta

    Descuento

    TotalCancelar

    en su experiencia que me puede decir de guardar el Id del usuario que realizo la venta y en que tabla es mejor guardar ese campo, en maestro o detalle.

    ahora estimado a medida que voy haciendo esto voy pensando en lo posterior 

    se que lo que se guarda no necesariamente debe ser lo que se muestra, me refiero a lo que voy a mostrar en el informe que pienso hacer con crystalReport y papel de impresora termica o impresoa que tenga papel de estos que nos dan en el super.

    por ejemplo en el reporte mostrare estos campos

    Nombre Producto     Unidad     Precio  Cantidad    Total

    Pan molde 10 un       bl              10         1            10

    y así sucesivamente. que me puede comentar de esto por favor

    mientras que en la bd guardo el id pero no la descripción del producto, porque con el id tengo lo demás no es cierto

    por favor que me puede decir de todo esto

    creo que el mas importante del programa es este formulario o estos

    Gracias

    pienso ocultar algunas columnas como Id y código.

    Roberto

    viernes, 27 de marzo de 2020 23:27
  • Buenas noches Roberto

    1) Si, me parece bien, no me había dado cuenta que aunque te compren 3 atrículos, los 3 registros apuntan a un "maestro venta", o sea está bien, habrá un único Id por cada venta. 

    1.a) Si, o igual cuando creas el registro el Id se pone solo, es autoincremental. Pero si, si tenes que averiguar cual Id es el siguiente, averiguas el mayor y le sumas 1. 

    SELECT MAX (Id) FROM Tabla

    2) No se para qué un numeroVenta de 200 si ya tenes el Id. No sabía que tendrás los clientes registrados como para usar un IdCliente, y si viene uno que no está registrado, cómo haces? Lo tenes que registrar? Y eso cómo lo haces? Tenes que armar otro Form para ingresar el Cliente. Y valorVenta yo lo pondría como float (o single, o como se llame el tipo en SQL), para qué tantos decimales? No, no me parece que falten sino que sobran.

    3) En Maestro, porque es una venta, un usuario. Si no, sería guardar el usuario por cada registro de venta, que comunmente serán más de uno.

    4) Si, con el Id tenes todo lo demás. No hay una única forma de diseñar la aplicación y los Forms que en ella van, gran parte de ese trabajo queda en el gusto o en el criterio del programador, mientras no haya errores lógicos ... 


    domingo, 29 de marzo de 2020 0:39
  • Tigre, buenas tardes.

    estoy haciendo los cambios y las observaciones.

    Estimado una pregunta.

    Cambien había pensado en eso del Cliente,lo hice así porque tal vez en algún momento se quiera dar un descuento a un cliente por cierto monto de compra.

    ya tengo mi formulario Cliente todo esta corriendo bien, ahora me gustaría hacer que cuando yo en el texbox vaya escribiendo el nombre del cliente me muestre en un desplegable los que sean Rubén por ejemplo. debe ser que esto va en un evento. pero lo que muestra abajo como en un combobox que control sería.

    otra cosa de no ir el cliente que otro campo puedo agregar en el maestroventa, ya que aveces las personas no quieren dar su nombre y sus datos.

    mi pregunta sería con que campos me quedaría de quitar el cliente. por favor

    Gracias

    Roberto

    domingo, 29 de marzo de 2020 18:41
  • Hola Roberto

    Para el "Autocomplete", que es el control que me decís que vayan apareciendo los nombres a medida que vas escribiendo, recuerdo haber visto y comentado en un post de este mismo Foro hace como un mes y medio, que se puede usar un TextBox común y corriente, que tiene una propiedad que se llama, más o menos,

    AutoCompleteSource

    o algo así

    Mira acá está

    https://stackoverflow.com/questions/4629909/how-to-make-an-auto-complete-textbox-in-a-winforms-desktop-application

    Y los datos que se me ocurren en el MaestroVenta son hora y fecha, número o Id, vendedor (No se si será uno solo), y me parece que el total a pagar no es necesario porque tenes los detalles que los sumas y ya está, aunque esto es a criterio del programador o del usuario de la aplicación

    Saludos

    martes, 31 de marzo de 2020 2:28
  • Buenas tardes Tigre. voy avanzando.

    ahora me puede ayudar con este inconveniente voy con las imágenes

    En este formulario guardo el producto y como Ud. puede ver en el campo Dir Imagen selecciono la imagen en el disco duro y se muestra en el Texbox la dirección o directorio.

    ahora a este producto debo en algun momento hacerle un mantenimiento, cambiar alguna cosa, el estado o incluso la imagen. y para ello prepare este otro formularios que es parecido

    pero si observa en la imagen siguiente en el campo imagen no me viene la dirección como en la imagen anterior.

    El sql query es este

    CREATE TABLE [dbo].[tblProducto](
    	[Id] [int] IDENTITY(1,1) NOT NULL,
    	[IdCategoria] [int] NOT NULL,
    	[IdUnidadMedida] [int] NOT NULL,
    	[Codigo] [varchar](200) NOT NULL,
    	[Descripcion] [varchar](500) NOT NULL,
    	[PrecioVenta][money] NULL, -- No puede ser NULL puede por lo menos ser Cero
    	[Stock][decimal](8,2) NULL,
    	[FechaCreado] [datetime] NOT NULL,
    	[NombreImagen] [varchar](100) NOT NULL, -- No la volví null porque quiero que se agregue una foto por defecto
    	[Imagen] [image] NULL,
    	[IdEstado][int] NOT NULL,
    	[IdUsuario][int] NOT null,
    	CONSTRAINT [PK_tblProducto] PRIMARY KEY CLUSTERED (Id),
    	CONSTRAINT [FK_tblUnidad] FOREIGN KEY (IdUnidadMedida) REFERENCES tblUnidad(Id),
    	CONSTRAINT [FK_tblUsuario] FOREIGN KEY (IdUsuario) REFERENCES tblUsuario(Id),
    	CONSTRAINT [FK_tblCategoria] FOREIGN KEY (IdCategoria) REFERENCES tblCategoria(Id),
    	CONSTRAINT FK_tblProducto_tblEstado FOREIGN KEY (IdEstado) REFERENCES tblEstado(Id)
    	);


    y como cargo los datos al formulario es este.

    public FrmEditarProducto(int IdProducto)
            {
                InitializeComponent();
                CargarUnidad();
                CargarEstados();
                CargarCategoria();
                this.IdProducto = IdProducto;
                var LineaProducto = Producto.SelectProductobyIdProducto(this.IdProducto);
                foreach (var item in LineaProducto)
                {
                    MemoryStream ms = new MemoryStream(item.Imagen);
                    Bitmap bitmap = new Bitmap(ms);
                    //
                    TxtId.Text = item.Id.ToString();
                    TxtCodigo.Text = item.Codigo;
                    TxtDescripcion.Text = item.Descripcion;
                    CboUnidad.SelectedValue = item.IdUnidadMedida;
                    txtPrecio.Text = item.PrecioVenta.ToString();
                    NudStock.Value = (decimal)item.Stock;
                    TxtDirImagen.Text = (item.Imagen).ToString();
                    TxtNombreImagen.Text = item.NombreImagen;
                    PtBoxImagen.Image = bitmap;
                    int Idc = item.IdCategoria;
                    // Combox
                    CboCategoria.SelectedValue = item.IdCategoria;
                    CboEstado.SelectedValue = item.IdEstado;
    
    
    
                    
                    
                }
            }

    Me puede ayudar o debo dejarlo en blanco ese campo por favor.

    por favor. 

    muchas gracias.

    Roberto

    jueves, 2 de abril de 2020 22:22
  • Buenas noches Roberto

    Te viene como un conjunto de System.Byte[] porque vos lo guardaste la imagen en la base de datos como tal, o como Bitmap, no como un string. Lo que tendrías que hacer es o guardarlo la ruta de archivo como un string, o poner un picturebox en el Form para que veas la imagen tal como la guardaste en la base de datos, o bien dar la posibilidad de elegir otra vez la imagen sin ver nada lo que hay (dado que lo que hay son Byte[] s).

    Además, me parece que el formulario en que agregas un producto y el que lo editas, debería ser el mismo, sólo que al editarlo, le ponés el Id en su TextBox, y si no (podes pasarle -1 por ejemplo) que cree un producto nuevo.


    viernes, 3 de abril de 2020 0:00
  • Estimado Tigre. buenas noches.

    Muy bien entiendo.

    lo dejo así. ya que esta bien de momento. 

    ahora, lo de los formularios, lo pensé también pero yo necesitaba el picturebox que en el de ingreso de productos no lo tengo. y quiero que para modificar se vea la imagen. y también porque va a tener roles, vale decir que el cajero no podrá cambiar los productos. sino otra persona con privilegios diferentes.

    y sí es el mismo formulario con la diferencia del PictureBox.

    ahora estimado Tigre una consulta, estoy queriendo que el producto se modifique tres veces. como puedo implementar esta parte por favor.

    Ahora otra cosa estimado he visto que que también debo guardar quien hizo la modificación, eso implica crear un campo mas en mi tabla, por ejemplo UpdateUserId, o crear una tabla mas. ya que también me gustaría guardar el producto anterior. tipo para hacer una auditoria.

    gracias  por sus orientaciones.

    Roberto

    viernes, 3 de abril de 2020 0:43
  • Hola Roberto

    Si queres que se vea la imagen, entonces pone un PictureBox y un MemoryStream para leer los bytes en un Bitmap.

    Podes hacer una tabla ProductosModificados con un UserId y algunos campos (o todos) de la tabla Producto, y con el mismo Id que el Producto modificado, pero que no sea la PK, así lo podrías modificar más de una vez, ... digo, no se, porque esta lógica es nueva para mi.

    sábado, 4 de abril de 2020 16:53
  • Estimado Tigre. buen día. espero que todo esté bien. 

    No he desistido estoy aun con inconvenientes leyendo un poco sobre maestrodetalle la verdad se me complico la parte del informe, pero no significa que deje de trabajar.

    estimado tengo una consulta, y viendo las categorías que tengo me di cuenta que lo tengo ya fijos esos botones.

    con tres categorías, y como ud. sabe siempre debemos pensar en lo que el cliente va a necesitar.

    mi duda es la siguiente como tendría que hacer el cliente si necesita crear otra categoría si ya los botones están fijos en el formulario, es por ello que pensé en crear mas botones en tiempo de ejecución, botones a los cuales deba ponerles un nombre asignarle un Tag y pues sus eventos.

    que me puede decir Ud. como puedo resolver este tema. la respuesta mas simple seria que que el cliente me busque y que yo cree e botón, y le pase el ejecutable, pero debe haber alguna forma de que el cliente, cree sus propios botones no es cierto.

    También había pensado en crear una tabla, pero que me recomienda Ud. o sus comentarios al respecto por favor.

    Gracias.

    Roberto

    jueves, 9 de abril de 2020 15:07
  • Hola Roberto

    Creo que el cliente tiene que armar a su propia manera todo lo que es productos, desde cero, pero que vos les tendrías que dar un papel con las indicaciones (quizás con algún ejemplo escrito - No hecho en el sistema), para que le resulte más agradable y no tedioso, o sea que lo pueda hacer con facilidad.

    Obviamente que los botones, tanto los del ToolStrip como los del FlowLayoutTable serán dinámicos, dependiendo de lo que haya en la base de datos. Por ejemplo, cada Producto debe tener una FK a su Categoría, además de precio de venta, costo, stock, etc.. Y tiene que haber un subsistema para ingresar las categorías y los productos en tablas de la base de datos. Luego, por ejemplo, por cada Categoría habrá un ToolStripButton que hará visualizar todos los productos de la misma. En el formulario de ingreso de Productos, por ejemplo, debe haber un comboBox para seleccionar su Categoría.

    Veo que vas avanzando, un poco más o un poco menos. Lo que si, vas a tener que testearlo muy bien y ver que todo anda perfecto, antes de venderlo.

    Saludos

    Pablo


    viernes, 10 de abril de 2020 19:06
  • Estimado Pablo, buen día.

    bien entonces vamos por el camino agradezco, ya tengo listo el informe o la venta que debo imprimir para el cliente.

    le muestro un poco

    y aquí el informe.

    hoy comienzo a trabajar sobre el ingreso de los productos y sus ventas y sus saldos.

    pienso hacer esta modelo

    _________________________________________

    Id  | Idproducto | Fecha | Ingreso | Egreso | Saldo

    _________________________________________

    Por favor si hay alguna sugerencia sobre esta parte le agradezco.

    estoy trabajando entonces.

    Gracias Estimado Pablo

    Roberto

    sábado, 11 de abril de 2020 14:55
  • Buenas tardes, Estimado Roberto

    Con respecto al ingreso de los productos, lo que te puedo decir, es que puede ser que lo anotes como gasto o no, si es que pensas llevar la contabilidad, y que para mi sería un simple incremento del campo stock de la tabla Productos, excepto que quieras guardar registro de los ingresos de stock, en este caso lo único que me hace dudar es el campo Egreso, no se cómo se podría dar, quizás si devolves mercadería a un proveedor?

    sábado, 11 de abril de 2020 21:57
  • Estimado Pablo buenas noches.

    voy yendo voy avanzando ya implemente la parte del ingreso del producto terminado vale decir

    Pan, Empanadas, Sodas o otros de las categorías.

    esto ya trabaja perfectamente, esto es un maestro detalle.

     ahora cuando hago el ingreso del producto terminado en simultaneo hago un ingreso a una tabla que le denomine Kardex

    y ya luego con esto hago una consulta para que me muestre los saldos

    hasta aquí voy bien, una de las inconsistencias es que hice una salida de un producto que no tiene ingreso

    ya lo resuelvo luego.

    ahora estimado Tigre por favor me gustaría que me ayude en la creación de los botones de la categoría, recuerda que le comente que eso lo debe hacer el propietario del sistema en base a las categorías que tiene activas.
    por favor me puede ayudar con esto.

    Gracias.

    Roberto

    miércoles, 15 de abril de 2020 23:31
  • Hola Roberto

    A ver cómo hacemos los botones de las Categorías y al hacer click, los botones de los productos ...

    // 1° Declarar miembros de clase
    
    private List<Button> botonesCategorias;
    private List<Button> botonesProductos;
    
    // 2° Con Entity Framework (que yo no lo se usar) conseguis un List<Categoria> categorias (si queres te lo hago en ADO.NET pero me dijiste que no)
    
    Button boton;
    botonesCategoria = new List<Button>();
    foreach (var categoria in categorias)
    {
        boton = new Button();
        // ver cuanto es ancho y alto
        boton.Size = new Size(ancho, alto);
        // ver cuanto es x e y
        boton.Location = new Point(x, y);
        // la imagen guardada en la base de datos
        boton.Image = categoria.Imagen;
        // el nombre de la categoría
        boton.Text = categoria.Nombre;
        // el ID de la categoría
        boton.Tag = categoria.ID.ToString();
        boton.Click += new EventHandler(botonCategoria_Click);
        botonesCategoría.Add(boton);    
    }
    
    // 3° el método botonCategoria_Click
    private void botonCategoria_Click(object sender, EventArgs e) 
    {
        Button boton = (Button)sender;
        string ID = boton.Tag;
        
        // con el ID conseguis todos los Productos cuya categoría es la misma del botón sobre el cual se clickeó
        // Con EF haces un List de todos esos Productos
        
        Button boton;
        botonesProductos = new List<Button>();
        foreach (var producto in Productos)
        {
            boton = new Button();
            boton.Size = new Size(ancho, alto);
            boton.Location = new Point(x, y);
            boton.Image = producto.Imagen;
            boton.Text = producto.Nombre;
            boton.Tag = producto.ID.ToString();
            boton.Click += new EventHandler(botonProducto_Click);
        }    
    }
    
    private void botonProducto_Click(object sender, EventArgs e) 
    {
        Button boton = (Button)sender;
        string ID = boton.Tag;
    
        // Aquí con el ID haces lo que queres con el Producto, vender, o lo que sea
    }

    Fijate que los métodos del evento Click, tanto para los botones de Categoría como para los de Productos, son los mismos, sólo que en cada llamado diferencian qué botón los llamó por el ID que viene en el Tag del Button, te acordas? 

    Sólo te faltaría a vos llenar lo de Entity Framework, que yo desconozco, y en el método del Click de Producto, ver qué vas a hacer con el Producto para ponerlo en la lista de Venta o lo que quieras.

    Decime si me faltó algo ... que no sea lo del EF por favor.

    Saludos

    Pablo

    viernes, 17 de abril de 2020 2:42
  • Estimado Pablo, gracias. por el código.

    un gran favor, puede por favor con ADO.NET mostrarme un ejemplo yo con mi poco conocimiento intentare hacerlo en EF, lo que pasa que quiero demorarme menos aquí ya que Ud. me esta ayudando con el Código .

    Lo que quiero es ver como hace y que es lo que me pide que haga. 

    si es una lista y creo yo que debo hacer un Count() para que el código sepa cuantos botones puedo hacer. 

    por favor

    muy amable

    Gracias

    Roberto

    viernes, 17 de abril de 2020 18:03
  • Estimado Pablo buenas tardes de nuevo bueno tengo el listado de Categorías. lo que me falta es crear un campo donde guardar la imagen (eso ya lo hago) de momento sin imagen puede funcionar no es cierto?

    esta es la imagen

    de momento tengo tres categorías.

    Ahora, por favor me va corrigiendo, Yo creo que al cargar el formulario es cuando ya debo crear los botones no es cierto?, Me refiero a los btns de las categorías.
    la otra pregunta al respecto que tengo es como lo ha visto, ya tengo los botones pero no son dinámicos, en que podría cambiar el código que tengo en la creación de los botones porque he visto este código 

    private List<Button> botonesProductos; lo que creo de este código es para crear botones, por favor me explica un poquito de este tema por favor Pablo

    aquí la imagen como Ud. sabe esto ya funciona, pero debo cambiar la forma de cargar los btns

    Gracias

    Roberto

    viernes, 17 de abril de 2020 19:11
  • Estimado Pablo buenas noches.

    por favor si puede no me responda a los dos mensajes anteriores, ya que pude hacer como me indicó, le muestro para que lo vea

    hay algunas cosas que debo resolver pero las pregunto en su momento son mas cambios de forma(bueno es lo que pienso) 

    Ahora estimado, una consulta (No diré la ultima porque seguro que vendrán mas).

    estoy ahora viendo la parte de arqueo de caja.pues que cada usuario cierre su caja a la hora de salir.

    por favor cual es la mecánica que debo implementar para tal efecto, ya que es primera vez que hago esto.

    Yo pensaba hacer un libro de ventas, en ella ingresar todas las ventas por día, por favor alguna idea de los campos que debo usar (Por favor) 

    Lo otro es el arqueo de caja, pienso yo que con un select  * from ventas where IdUser = 1 and datesales Today() por favor me puede dar ideas de como hacer esta parte de todas formas yo también investigo algo pero me gustaría que me de sugerencias.

    he visto algunos formatos interesantes pero lo que no he visto es como se implementa entre tablas y consultas.

    gracias.

    Roberto

    viernes, 17 de abril de 2020 23:27
  • Buenas noches Roberto

    La verdad yo tampoco tengo experiencia en arqueo, pero supongo que tendrías que hacer una consulta (SQL o con EF que no se si se puede), que sume todas las ventas (cada una de las ventas con todas sus respectivas anotaciones, por ejemplo, una venta puede ser un sandwich y una bebida, o sea no es una sola cosa) y anote la suma en una tabla Arqueo con el Id del vendedor y la hora de cierre, y también la hora cuando comienza. 

    sábado, 18 de abril de 2020 0:37