none
Ejecutar un metodo desde el datagrid RRS feed

  • Pregunta


  • Buenas tardes,

    Estoy haciendo una aplicacionen WPF y me ha surgido el siguiente problema que no consigo resolver, seguro que es una chorrada pero no hay manera.

    Tengo el siguiente datagrid

    <DataGrid x:Name="Venta_Articulos_G" IsEnabled="False"
                      AutoGenerateColumns="False" GridLinesVisibility="None"
                      Width="684" Height="278" Grid.Row="3" Grid.RowSpan="7" Margin="70,35,0,0"
                      HorizontalAlignment="Left" VerticalAlignment="Top" 
                      MouseDoubleClick="MostrarArticulo" CellEditEnding="ModificarDescuento">
                <DataGrid.Columns>
                    <DataGridTextColumn IsReadOnly="True" Header="Id"     Binding="{Binding Path=ArticuloId}" Visibility="Hidden"></DataGridTextColumn>
                    <DataGridTextColumn IsReadOnly="True" Header="Codigo" Binding="{Binding Path=Codigo}" Visibility="Hidden"></DataGridTextColumn>
                    <DataGridTextColumn IsReadOnly="True" Header="Clase"  Binding="{Binding Path=Clase.Nombre}" MinWidth="50"></DataGridTextColumn>
                    <DataGridTextColumn IsReadOnly="True" Header="Modelo" Binding="{Binding Path=Modelo.Nombre}" MinWidth="50"></DataGridTextColumn>
                    <DataGridTextColumn IsReadOnly="True" Header="Talla"  Binding="{Binding Path=Talla}" MinWidth="50"></DataGridTextColumn>
    
                    <DataGridTemplateColumn Header="Modos" MinWidth="150">
                        <DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <TextBlock Width="138" Text="{Binding Modo.Nombre}"/>
                            </DataTemplate>
                        </DataGridTemplateColumn.CellTemplate>
    
                        <DataGridTemplateColumn.CellEditingTemplate>
                            <DataTemplate>
                                <ComboBox Width="148" Height="21" Loaded="CargarModos" SelectionChanged="ModificarModo" SelectedItem="{Binding Modo.Nombre}"/>
                            </DataTemplate>
                        </DataGridTemplateColumn.CellEditingTemplate>
    
                    </DataGridTemplateColumn> 
    
                    <DataGridTextColumn IsReadOnly="True" Header="Precio" Binding="{Binding Precio, StringFormat='{}{0:c}'}" MinWidth="75"></DataGridTextColumn>
                    <DataGridTextColumn Header="Descuento" Binding="{Binding Descuento, StringFormat='{}{0}%'}" MinWidth="75"></DataGridTextColumn>
                    <DataGridTextColumn IsReadOnly="True" Header="Total" Binding="{Binding Total, StringFormat='{}{0:c}'}" MinWidth="75"></DataGridTextColumn>
                    <DataGridTextColumn Header="Señal" Binding="{Binding Señal, StringFormat='{}{0:c}'}" MinWidth="75"></DataGridTextColumn>
                </DataGrid.Columns>
            </DataGrid>

    Como podeis ver casi todas las columnas son de modo solo lectura salvo 3; la primera es una columna que contiene un combobox y lanza el evento SelectionChanged, este metodo me funciona correctamente y hago lo que quiero, el problema lo tengo con las otras 2 columnas que pueden editarse.

    La columna descuento y la columna Señal, la pregunta es ¿ Como puedo hacer que cada una de estas columnas lance un evento cuando se modifica el dato ? he probado con

    CellEditEnding="ModificarDescuento"


    El problema es que este metodo se ejecuta cunado modifico cualquiera de las 2 columnas y no es lo que quiero, sino que quiero que cada una lance un evento diferente.

    Se que creando una columna personalizada como textbox me permite lanzar un evento pero queda muy mal ya que se nota el cuadro de texto en el grid.

    ¿ alguna idea ?

    Por otra parte a la hora de modificar una celda es posible que el texto existente se seleccione por defecto para que cuando vayan a escribir lo demas se haya borrado.

    Gracias por su ayuda


    miércoles, 21 de enero de 2015 18:51

Respuestas

  • Hola Veleras, puedes pregunta por el Header de tu celda en cuestión (cómo lo muestro abajo) o puedes preguntar por la propiedad Name (debes agregar dicho atributo en los campos editables, no al combox, que ya te funciona). De manera a que en tu evento CellEditEnding="ModificarCampos" puedas hacer la pregunta ;)

    Quedaría algo así:

    private void ModificarCampos(object sender, DataGridCellEditEndingEventArgs e)
    {
        if (e.Column.Header!= null && e.Column.Header.ToString().Equals("Descuento", StringComparison.OrdinalIgnoreCase))
        {
            //Es la celda de descuento por lo tanto escribe tu codigo aquí
           
        }
    }

    o bien algo así:

    En tu XAML...

     <DataGridTextColumn Name="colDescuento" Header="Descuento" Binding="{Binding Descuento, StringFormat='{}{0}%'}" MinWidth="75"></DataGridTextColumn>

    Y en el evento CellEditEnding...

    private void ModificarCampos(object sender, DataGridCellEditEndingEventArgs e)
    {
        if (e.Column.Name.Equals("colDescuento", StringComparison.OrdinalIgnoreCase))
        {
            //Es la celda de descuento por lo tanto escribe tu codigo aquí
           
        }
    }

    Espero resulte útil.

    Saludos


    Christian Amado
    Software Engineer | MCPD: Windows Phone Developer | MCTS: Silverlight Developer
    Don't forget to mark the right answer and vote up if helps you.
    MCP Profile

    • Marcado como respuesta Veleras sábado, 24 de enero de 2015 18:17
    viernes, 23 de enero de 2015 12:10

Todas las respuestas

  • Hola Veleras, puedes pregunta por el Header de tu celda en cuestión (cómo lo muestro abajo) o puedes preguntar por la propiedad Name (debes agregar dicho atributo en los campos editables, no al combox, que ya te funciona). De manera a que en tu evento CellEditEnding="ModificarCampos" puedas hacer la pregunta ;)

    Quedaría algo así:

    private void ModificarCampos(object sender, DataGridCellEditEndingEventArgs e)
    {
        if (e.Column.Header!= null && e.Column.Header.ToString().Equals("Descuento", StringComparison.OrdinalIgnoreCase))
        {
            //Es la celda de descuento por lo tanto escribe tu codigo aquí
           
        }
    }

    o bien algo así:

    En tu XAML...

     <DataGridTextColumn Name="colDescuento" Header="Descuento" Binding="{Binding Descuento, StringFormat='{}{0}%'}" MinWidth="75"></DataGridTextColumn>

    Y en el evento CellEditEnding...

    private void ModificarCampos(object sender, DataGridCellEditEndingEventArgs e)
    {
        if (e.Column.Name.Equals("colDescuento", StringComparison.OrdinalIgnoreCase))
        {
            //Es la celda de descuento por lo tanto escribe tu codigo aquí
           
        }
    }

    Espero resulte útil.

    Saludos


    Christian Amado
    Software Engineer | MCPD: Windows Phone Developer | MCTS: Silverlight Developer
    Don't forget to mark the right answer and vote up if helps you.
    MCP Profile

    • Marcado como respuesta Veleras sábado, 24 de enero de 2015 18:17
    viernes, 23 de enero de 2015 12:10
  • Lo que usted quiere es muy sencillo en WPF si se sigue correctamente el patrón MVVM. Usted debería tener en el ViewModel una propiedad que devuelve una colección de objetos que representan las filas del DataGrid. Dichos objetos tendrán propiedades que representan una columna del DataGrid. Dichos objetos heredan de la clase DependencyObject y sus propiedades son dependency properties, o bien dichos objetos implementan INotifyPropertyChanged.

    Cuando el valor se cambia a través de la grilla, los objetos reciben el nuevo valor en su propiedad y el cambio es anunciado, ya sea a través del mecanismo de notificación de dependency properties o bien mediante el evento PropertyChanged.  Entonces lograr lo que usted quiere es automático.  Simplemente escuche por el evento PropertyChanged y listo:  Es notificado cuando el valor cambia, tanto por interacción con la grilla como por cambios por código.


    Jose R. MCP
    Code Samples

    viernes, 23 de enero de 2015 14:30
  • Muchas gracias por tu ayuda Christian.

    La primera solución es la que me ha servido, aunque en principio me resultaba mas atractiva la segunda esta no la he podido aplicar ya que el atributo Name no existe en DataGridTextColumn no da la opción y si lo incluyes dd todas formas este no complica.

    La primera funciona a las mil maravillas.

    Gracias de nuevo

    sábado, 24 de enero de 2015 18:20