none
Suma Acumulada en un TextBox RRS feed

  • Pregunta

  • Tengo un textbox que me va acumulando el importe de cada articulo que agrego a un datagrid, entonces cuando elimino uno de esos artículos agregados quisiera que al total acumulado que tengo en el textbox se le reste dicho articulo.. Trabajo en

    VS2012 C#

    martes, 9 de diciembre de 2014 14:57

Respuestas

  • hola

    pero porque en cada accion no recalcular el total completo, ya sea que agregues o elimines simplemente usarias


    decimal total = GridView1.Rows.Cast<GridViewRow>().Sum(r=> Convert.ToDecimal(r.Cells[2].Text));
    
    txtImporte.Text = total.ToString("N2");


    de esta forma es directo y no necesitas ninguna variable en session o viewstate, simplemente calculas y lo haces con linq asi queda mas simple el codigo

    en ese caso r.Cells[2] seria la columna que representa el importe del producto, si necesitas algo mas complejo como importe por cantidad tambien se puede lograr

    .Sum(r=> Convert.ToDecimal(r.Cells[2].Text) * Convert.ToInt32(r.Cells[3].Text));

    alli los indices de las columnas estas inventados, tu pondrias los reales, sera el "2" el importe y el "3" la cantidad

    saludos


    Leandro Tuttini

    Blog
    MVP Profile
    Buenos Aires
    Argentina

    • Marcado como respuesta Argenis R R martes, 9 de diciembre de 2014 17:17
    martes, 9 de diciembre de 2014 15:32

Todas las respuestas

  • Puesto que escribe en el foro de ASP.net asumo que está hablando del GridView y que su proyecto es ASP.net Web Forms.

    No sé qué tan grande sea su grilla en términos de filas (registros), pero lo más simple sería tener una función que totalice cada vez que se cambie algo en la fuente de datos, que idealmente sería una colección de algún tipo, como por ejemplo List<Tipo>.  Alternativamente si tiene todo bien sincronizado y el total en una variable a nivel de formulario web (Page) o bien desde el ViewState, podría simplemente restar al total precalculado en el evento GridView.RowDeleting.

    Mi programación sería algo como:

    1. Declarar una propiedad en la clase Page llamada Total que almacenaría en ViewState.
    2. En el Page_Load haría lo usual, que sería asignar el DataSource al GridView; si no es PostBack tambiíen haría un DataBind().
    3. En el Page_Load calcularía el total y lo asignaría a la propiedad Total si no fuera un PostBack.
    4. En el evento RowDeleting actualizaría la propiedad Total como Total -= <valor a restar debido a la eliminación de fila>.
    5. En el evento Page_PreRender asignaría Total.ToString() a la propiedad Text de la casilla de texto que usted dice tener para mostrar el total.

    Jose R. MCP
    Code Samples

    martes, 9 de diciembre de 2014 15:07
    Moderador
  • Disculpa por la rapidez no me fije en que foro publique. Trabajo en Windows Forms
    martes, 9 de diciembre de 2014 15:21
  • hola

    pero porque en cada accion no recalcular el total completo, ya sea que agregues o elimines simplemente usarias


    decimal total = GridView1.Rows.Cast<GridViewRow>().Sum(r=> Convert.ToDecimal(r.Cells[2].Text));
    
    txtImporte.Text = total.ToString("N2");


    de esta forma es directo y no necesitas ninguna variable en session o viewstate, simplemente calculas y lo haces con linq asi queda mas simple el codigo

    en ese caso r.Cells[2] seria la columna que representa el importe del producto, si necesitas algo mas complejo como importe por cantidad tambien se puede lograr

    .Sum(r=> Convert.ToDecimal(r.Cells[2].Text) * Convert.ToInt32(r.Cells[3].Text));

    alli los indices de las columnas estas inventados, tu pondrias los reales, sera el "2" el importe y el "3" la cantidad

    saludos


    Leandro Tuttini

    Blog
    MVP Profile
    Buenos Aires
    Argentina

    • Marcado como respuesta Argenis R R martes, 9 de diciembre de 2014 17:17
    martes, 9 de diciembre de 2014 15:32
  • Moveré entonces su pregunta al foro correspondiente.

    Para Windows Forms usted puede usar Data Binding.  El datagrid entonces supongo que es un DataGridView.  ¿Usa data binding?  Debería.  Entonces usted tendría un formulario (clase Form) y tendría una lista de algún tipo para hacer el data binding.  Para Windows Forms yo suelo usar un BindingList<>, pero un ObservableCollection<> también es buena opción.  El tipo de item de la colección debería implementar INotifyPropertyChanged para que Data Binding sea la octava maravilla.

    La clase BindingList tiene el evento ListChanged.  Simplemente utilice dicho evento para detectar el cambio en la cantidad de registros y actualice el textbox.

    //Declare su fuente de datos a nivel de formulario:
    private BindingList<Dato> _datos;
    
    //Declare una propiedad Total a nivel de formulario:
    private double Total { get; set; }
    
    //En Form_Load o similar cargue los datos desde su fuente de datos:
    private void Form_Load(object sender, EventArgs e)
    {
        //DataLayer.LeerDatos() sería un método que devuelve un tipo IEnumerable<Dato>.
        _datos = new BindingList<Dato>(DataLayer.LeerDatos());
        //Asigne el DataSource del DGV
        dgv1.DataSource = _datos;
        //Controle el evento ListChanged:
        _datos.ListChanged += OnListChanged;
        //Calcule el total.
        CalcularTotal();
    }
    
    private void CalcularTotal()
    {
        double total = 0;
        foreach (Dato dato in _datos)
        {
            total += dato.PropiedadATotalizar;
        }
        Total = total;
    }
    
    //Y este sería el lugar donde actualizaría el total:
    private void OnListChanged(object sender, ListChangedEventArgs e)
    {
        if (e.ListChangedType == ListChangedType.ItemDeleted)
        {
            Total -= _datos[e.NewIndex].PropiedadATotalizar;
        }
    }

    Y creo que eso sería todo.  Es un ejemplo sumamente sencillo.

    Alternativamente podría mover el desarrollo de su aplicación Windows Forms al modelo MVVM y más bien crear una clase VM que contenga los datos en una propiedad y la propiedad Total, luego haría DataBinding del textbox así como de la grilla.


    Jose R. MCP
    Code Samples

    martes, 9 de diciembre de 2014 15:37
    Moderador
  • Realmente es mas sencillo de esta forma
    lunes, 27 de julio de 2015 16:05