none
Sumar el resultado de dos columnas en una tercera en un DataGrid de Wpf con EF y C# RRS feed

  • Pregunta

  • Buenas noches, he leido cosas con respecto a este tema pero aun no estoy muy claro sobre como hacer para poder tener simplemente el resultado de la suma de dos columnas en una tercera.

    Lo que he leido en otros foros me ha alludado un poco pero quisiera saber si pueden colocarme un ejemplo sencillo sobre el caso.

    Se que en el codigo XAML tengo que usar en el Binding la opción Mode = TwoWay y asi he hecho en mi codigo XAML, lo tengo asi:

    <Window x:Class="Inventario.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow" Height="400" Width="973" Loaded="Window_Loaded" Activated="Window_Activated">
        <Grid>
            <DockPanel  Name="dockPanel1" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="12,118,12,58" >
                <DataGrid AutoGenerateColumns="False"  Name="gr_inv" Width="928" Background="#90688CAF" RowBackground="#8FFFFFFF"> 
                    <DataGrid.Columns>
                        <DataGridTextColumn Header="Reng"          Width="40"  Binding="{Binding Path= 0}"></DataGridTextColumn>
                        <DataGridTextColumn Header="Código"        Width="200" Binding="{Binding Path= co_art}"    IsReadOnly="True"> </DataGridTextColumn>
                        <DataGridTextColumn Header="Descripción"   Width="400" Binding="{Binding Path= art_des}"   IsReadOnly="True"> </DataGridTextColumn>
                        <DataGridTextColumn Header="Stock Teorico" Width="85"  Binding="{Binding Path= stock_act, StringFormat=\{0:N2\}}" IsReadOnly="True"> </DataGridTextColumn>
                        <DataGridTextColumn Header="Stock Real"    Width="85"  Binding="{Binding Path= stock_act2,Mode=TwoWay, StringFormat=\{0:N2\}}" IsReadOnly="False"></DataGridTextColumn>
                        <DataGridTextColumn Header="Diferencia"    Width="85" Binding="{Binding Path= res, StringFormat=\{0:N2\}}" IsReadOnly="True"></DataGridTextColumn>
                    </DataGrid.Columns>
                </DataGrid>
            </DockPanel>
            <ComboBox Height="25" HorizontalAlignment="Left" Margin="50,45,0,0" Name="combo_alma" VerticalAlignment="Top" Width="158" DropDownClosed="combo_alma_DropDownClosed" />
            <TextBox Height="27" HorizontalAlignment="Left" Margin="214,45,0,0" Name="txt_alma" VerticalAlignment="Top" Width="598" />
            <DatePicker Height="25" HorizontalAlignment="Left" Margin="708,79,0,0" Name="datePicker1" VerticalAlignment="Top" Width="104" />
            <Label Content="Fecha del inventario:" Height="25" HorizontalAlignment="Left" Margin="583,79,0,0" Name="label1" VerticalAlignment="Top" Width="119" />
        </Grid>
    </Window>


    Todas las columnas menos la penultima son de solo lectura, en la que no lo es es donde cambiare los numeros que originalmente me trae la consulta y me debe dar la diferencia en la tercera columna.

    En cuanto a la forma de llenar el DataGrid lo hago de la siguiente forma:

     private void combo_alma_DropDownClosed(object sender, EventArgs e)
            {
                if (combo_alma.Text == "")
                {
                    MessageBox.Show("Debe seleccionar un almacen");
                }
                else
                {
                    List<carga_grid> cg = (from a in inv.st_almac
                                           join b in inv.art on a.co_art equals b.co_art
                                           where b.campo8 == "Inventario" && a.co_alma == combo_alma.Text
                                           select new carga_grid()
                                           {
                                               co_art = a.co_art,
                                               art_des = b.art_des,
                                               stock_act = a.stock_act,
                                               stock_act2 = a.stock_act,                                           
                                           }).ToList();


                    gr_inv.ItemsSource = cg;
                }
                
                var d_alma = from da in inv.sub_alma
                             where da.co_sub == combo_alma.Text
                             select new { da.des_sub};


                txt_alma.Text = d_alma.Select(x => x.des_sub).First();
            }

            public class carga_grid 
            {
                public string co_art { get; set; }
                public string art_des { get; set; }
                public decimal stock_act { get; set; }
                public decimal stock_act2 { get; set; }           
            }

    Espero como simpre contar con su ayuda y desde ya muchas gracias.


    C. Zapata

    viernes, 17 de febrero de 2012 1:13

Respuestas

  • Fernando me parece interesante tu solución, intente usar esto pero me da un error con el ExpressionConverter no se que estoy haciendo mal 

    C. Zapata

    Si vas a:
    http://wpfconverters.codeplex.com/releases/view/77134

    Encontraras una descarga con toda la documentación del proyecto. Lo primero que deberías tener en cuenta es que hay que instalar los wpfconverters... Esto lo puedes hacer nuget y tendrás menos problemas :)


    Fernanando Escolar - http://www.programandonet.com/ - @fernandoescolar

    • Propuesto como respuesta pbousan lunes, 20 de febrero de 2012 8:22
    • Votado como útil pbousan lunes, 20 de febrero de 2012 8:25
    • Marcado como respuesta CAZA - domingo, 11 de marzo de 2012 3:14
    sábado, 18 de febrero de 2012 10:01
  • Eso ocurre porque no tienes implementada la propiedad INotifyPropertyChanged. Busca por internet un ViewModelBase y lo que haces es que tu clase herede de ViewModelBase, y luego cuando defines tus propiedades haces que en el set se haga una llamada a OnPropertyChanged (o como lo hayan llamado en el ViewModelBase que hayas descargado). Haciendo eso debería actualizarse automáticamente.

    Si no encuentras los códigos te los paso, pero en Visual Basic, que en C# me pierdo un poco.

    Espero haberte ayudado.


    Carlos Adrián Martínez

    • Marcado como respuesta CAZA - domingo, 11 de marzo de 2012 3:14
    sábado, 18 de febrero de 2012 18:32

Todas las respuestas

  • Hola,

    Podrías usar un ExpressionConverter (http://wpfconverters.codeplex.com/). Con esto tendrías que poner un código de binding semejante a este:

    <MultiBinding Converter="{ExpressionConverter {}{0} + {1}}">
       <Binding Path="Propiedad1" />
       <Binding Path="Propiedad2" />
    </MultiBinding>
    Un saludo,


    Fernanando Escolar - http://www.programandonet.com/ - @fernandoescolar

    viernes, 17 de febrero de 2012 8:28
  • Yo creo que lo más sencillo es añadir una propiedad SumaStock, la cargas en carga_grid como la suma de stock_act y stock_act2 y la enlazas a una columna del datagrid.

    Carlos Adrián Martínez


    • Editado Carlos Adrián viernes, 17 de febrero de 2012 10:41
    • Propuesto como respuesta Antonio Lobo sábado, 18 de febrero de 2012 12:54
    viernes, 17 de febrero de 2012 10:40
  • Hola Carlos, gracias por responder ya logre que me trajera el valor sumado atravez de una propiedad pero para la columna pero cuando actualizo los valores en mi columna editable no se como hacer para que cambie en la columna donde mecoloca los resultados. Puedes darme un ejemplo claro por favor.

    C. Zapata

    sábado, 18 de febrero de 2012 3:18
  • Fernando me parece interesante tu solución, intente usar esto pero me da un error con el ExpressionConverter no se que estoy haciendo mal 

    C. Zapata

    sábado, 18 de febrero de 2012 3:22
  • Hola Carlos, gracias por responder ya logre que me trajera el valor sumado atravez de una propiedad pero para la columna pero cuando actualizo los valores en mi columna editable no se como hacer para que cambie en la columna donde mecoloca los resultados. Puedes darme un ejemplo claro por favor.

    C. Zapata

    Hola, deberías implementar INotifyPropertyChange. Y en cada una de las propiedades, en el "set", lanzar el evento PropertyChanged (este evento lo implementas con la interface mencionada) para todas las propiedades que se hayan modificado.

    De esta forma consigues que se actualicen "dinámicamente" los bindings en pantalla.


    Fernanando Escolar - http://www.programandonet.com/ - @fernandoescolar

    • Propuesto como respuesta Antonio Lobo sábado, 18 de febrero de 2012 12:54
    sábado, 18 de febrero de 2012 9:53
  • Fernando me parece interesante tu solución, intente usar esto pero me da un error con el ExpressionConverter no se que estoy haciendo mal 

    C. Zapata

    Si vas a:
    http://wpfconverters.codeplex.com/releases/view/77134

    Encontraras una descarga con toda la documentación del proyecto. Lo primero que deberías tener en cuenta es que hay que instalar los wpfconverters... Esto lo puedes hacer nuget y tendrás menos problemas :)


    Fernanando Escolar - http://www.programandonet.com/ - @fernandoescolar

    • Propuesto como respuesta pbousan lunes, 20 de febrero de 2012 8:22
    • Votado como útil pbousan lunes, 20 de febrero de 2012 8:25
    • Marcado como respuesta CAZA - domingo, 11 de marzo de 2012 3:14
    sábado, 18 de febrero de 2012 10:01
  • Eso ocurre porque no tienes implementada la propiedad INotifyPropertyChanged. Busca por internet un ViewModelBase y lo que haces es que tu clase herede de ViewModelBase, y luego cuando defines tus propiedades haces que en el set se haga una llamada a OnPropertyChanged (o como lo hayan llamado en el ViewModelBase que hayas descargado). Haciendo eso debería actualizarse automáticamente.

    Si no encuentras los códigos te los paso, pero en Visual Basic, que en C# me pierdo un poco.

    Espero haberte ayudado.


    Carlos Adrián Martínez

    • Marcado como respuesta CAZA - domingo, 11 de marzo de 2012 3:14
    sábado, 18 de febrero de 2012 18:32