none
Como pasar el foco de un textbox a otro en un Datagrid? RRS feed

  • Pregunta

  • Hola Amigos, pues eso, estoy implententando un codigo que el compañero del foro David Gonzalez me paso anteriormente para modificar los datagrid, ahora tengo una duda, cuando pulso enter paso de un textbox a otro sin porblemas pero el foco no lo pasa, lo digo por que no puedo editar en ese textbox en especial, debo pulsar en el con el raton, entonces lo que he pensado es en el metodo pulsarTeclaEnter  al final buscar el textbox con DataRowview drw = (DatarowView)dataGrid1.FindName("password")  y despues pasarlo a un textbox para poner este en estado focus(); pero no me es valido, os pongo el codigo.

    <UserControl x:Class="Profesores.simulacion"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
                 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
                 mc:Ignorable="d" 
                 d:DesignHeight="300" d:DesignWidth="500">
        <Grid>
            <DataGrid AutoGenerateColumns="false" 
                      Height="251" 
                      HorizontalAlignment="Left" 
                      Margin="12,12,0,0" 
                      Name="dataGrid1" 
                      VerticalAlignment="Top" 
                      Width="479" 
                      AlternatingRowBackground="LightGray" 
                      CanUserResizeColumns="False"
                      CanUserResizeRows="False"
                      CanUserAddRows="False"
                      SelectionMode="Single"
                      SelectionUnit="Cell" 
                      IsTabStop="False">
                <DataGrid.Columns>    
                    <DataGridTemplateColumn Header="id" Width="70">
                        <DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <TextBlock Text="{Binding id}" MouseLeftButtonUp="soltarBotonIzquierdoRaton"/>
                            </DataTemplate>
                        </DataGridTemplateColumn.CellTemplate>
                    </DataGridTemplateColumn>
    
    
                    <DataGridTemplateColumn Header="usuario" Width="70">
                        <DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <TextBox Name="usuario" Text="{Binding usuario, Mode=TwoWay}" KeyDown="pulsarTeclaEnter"/>
                            </DataTemplate>
                        </DataGridTemplateColumn.CellTemplate>
                    </DataGridTemplateColumn>
    
                    <DataGridTemplateColumn Header="password" Width="70">
                        <DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <TextBox Name="password" Text="{Binding password, Mode=TwoWay}" KeyDown="pulsarTeclaEnter"/>
                            </DataTemplate>
                        </DataGridTemplateColumn.CellTemplate>
                    </DataGridTemplateColumn>
    
                    <DataGridTemplateColumn Header="nombre" Width="70">
                        <DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <TextBox Name="nombre" Text="{Binding nombre, Mode=TwoWay}" KeyDown="pulsarTeclaEnter"/>
                            </DataTemplate>
                        </DataGridTemplateColumn.CellTemplate>
                    </DataGridTemplateColumn>
    
                    <DataGridTemplateColumn Header="apellidos">
                        <DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <TextBox Name="apellidos" Text="{Binding apellidos, Mode=TwoWay}" KeyDown="pulsarTeclaEnter"/>
                            </DataTemplate>
                        </DataGridTemplateColumn.CellTemplate>
                    </DataGridTemplateColumn>
                </DataGrid.Columns>
            </DataGrid>
        </Grid>
    </UserControl>
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    using System.Data;
    using System.Data.SqlClient;
    using System.Windows.Controls.Primitives;
    
    namespace Profesores
    {
        /// <summary>
        /// Interaction logic for simulacion.xaml
        /// </summary>
        public partial class simulacion : UserControl
        {
           
    
            public simulacion()
            {
                InitializeComponent();
                Modelos.Clase_Usuarios controladorVista = new Modelos.Clase_Usuarios();
                controladorVista.mostrarUsuarios();
                SqlDataAdapter adaptador = new SqlDataAdapter();
                adaptador = controladorVista.getconsultaUsuariosDA();
                DataSet datos = new DataSet();
                adaptador.Fill(datos, "Usuarios");
                dataGrid1.ItemsSource = datos.Tables[0].DefaultView;
                controladorVista.cerrarConexion();
    
                DataRowView nuevoRow = ((DataView)dataGrid1.ItemsSource).AddNew();
    
                nuevoRow.Row[0] = "-1";
                nuevoRow.Row[1] = "";
                nuevoRow.Row[2] = "";
                nuevoRow.Row[3] = "";
                nuevoRow.Row[4] = "";
    
                
    
    
    
    
            }
            private void soltarBotonIzquierdoRaton(object sender, MouseButtonEventArgs e)
            {
                DataRowView drv = (DataRowView)dataGrid1.CurrentItem;
                int idActual = (int)drv.Row[0];
    
                if (idActual != -1)
                {
                  //  MessageBox.Show("NO ES LA -1");
                  //  MessageBox.Show(idActual.ToString());
                }
                else
                {
                  //  MessageBox.Show("ESTA ES LA -1");
                  //  MessageBox.Show(idActual.ToString());
                }
            }
    
            private void FinEditarCeldas(object sender, DataGridCellEditEndingEventArgs e)
            {/*
                //string oString = dataGrid1[dataGrid1.CurrentCell.Column.DisplayIndex, dataGrid1.CurrentCell.].ToString();
                DataRowView dr = e.Row.Item as DataRowView;
                //DataRowView dr = dataGrid1.CurrentCell.Item as DataRowView;
                dr.EndEdit();
    
    
    
                int id = (int)dr.Row[0];
                string usuario = dr.Row[1].ToString();
                string password = dr.Row[2].ToString();
                string nombre = dr.Row[3].ToString();
                string apellidos = dr.Row[4].ToString();
                MessageBox.Show(id + usuario + password + nombre + apellidos);
    
    
                // object celda = (DataGridCell)dataGrid1.ItemContainerGenerator.ContainerFromIndex(0);
                // MessageBox.Show(celda.ToString());*/
    
                //SABER COLUMNA
                /*
                int index = this.dataGrid1.SelectedCells[4].Column.DisplayIndex;
                MessageBox.Show(index.ToString());
                */
    
               /*
                DataGridCell cell = GetCell(2, 3);
                TextBlock tb = cell.Content as TextBlock;
                MessageBox.Show(Convert.ToString(tb));
                */
    
              
    
            }
    
    
            private void insertarNuevoRow(object sender, MouseButtonEventArgs e)
            {
    
                DataRowView drv = (DataRowView)dataGrid1.CurrentItem;
                int idActual = (int)drv.Row[0];
    
                if (idActual == -1)
                {
                    // LLAMO A LA DDBB Y ME DEVUELVE EL ULTIMO ID Y SE LO ASIGNAMOS
                    drv.Row[0] = 200;
                    dataGrid1.EndInit();
    
    
    
                    // CREAMOS UN NUEVO ROW
                    DataRowView nuevoRow = ((DataView)dataGrid1.ItemsSource).AddNew();
                    nuevoRow.Row[0] = "-1";
                    nuevoRow.Row[1] = "";
                    nuevoRow.Row[2] = "";
                    nuevoRow.Row[3] = "";
                    nuevoRow.Row[4] = "";
    
                }
    
                else
                {
    
                    // SABER LA POSICION DE LA COLUMNA
                    int indiceColumnaActual2 = dataGrid1.CurrentColumn.DisplayIndex;
                   // MessageBox.Show(Convert.ToString(indiceColumnaActual2));
                }
            }
    
    
            private System.Data.DataRowView getListItem(FrameworkElement _element)
            {
                if (_element != null)
                {
                    // obtener el item de la lista
                    DataGridRow item = (DataGridRow)dataGrid1.ContainerFromElement(_element);
                    if (item != null)
                    {
                        // obtener el indice del item de la lista
                        int index = dataGrid1.ItemContainerGenerator.IndexFromContainer(item);
                        // retornar la vista de la fila con los datos
                        return (System.Data.DataRowView)dataGrid1.Items[index];
                    }
                }
    
                // si no se encuentra se retorna null
                return null;
            }
    
            private void pulsarTeclaEnter(object sender, KeyEventArgs e)
            {
                
    
                if ((e.Key == Key.Enter || e.Key == Key.Return))
                { 
                    switch (e.OriginalSource.GetType().Name)
                    {
                        case "TextBox":
                            
                            TextBox text = (TextBox)e.OriginalSource;
                            DataRowView data = getListItem((FrameworkElement)e.OriginalSource);
    
                            string id2 = data.Row["id"].ToString();
                            string usuario2 = data.Row["usuario"].ToString();
    
                          //  MessageBox.Show("Perdido el foco en el TextBox: " + text.Text + " id " + id2);
    
                            break;
                    }
                }
    
                if ((e.Key == Key.Enter || e.Key == Key.Return) && e.Source.GetType().Name == "TextBox")
                {
                    // obtener el textbox
                    TextBox text = (TextBox)e.OriginalSource;
                    // evento manejado
                    e.Handled = true;
                    // mover el foco al siguiente control (esto se debe realizar adecuandolo a la situacion)
                    text.MoveFocus(new TraversalRequest(FocusNavigationDirection.Next));
    
                   // DataRowView data = getListItem((FrameworkElement)e.OriginalSource);
    
               
                    
                    
                    
                }       
    
            }
    
      
     
        }
    }
    Saludos.

    jueves, 1 de abril de 2010 17:44

Respuestas

  • Hola WpfSoft.

    Como son plantillas no puedes acceder a los elementos visuales por los medios tradicionales.

    la forma mas facil que tienes para cambiar focos, es guardando las referencias a los TextBox en el orden que se vayan creando y de paso te servira para ir pasando de uno a otro en el orden que los vayas insertando en la lista, que por defecto sera en orden de celdas.

    para realizar esto, puedes hacer algo como lo siguiente:

    codigo xaml de las plantillas con los texBox:

    <DataGridTemplateColumn Header="nombre" Width="70">
        <DataGridTemplateColumn.CellTemplate>
            <DataTemplate>
                <TextBox Text="{Binding Mode=TwoWay, Path=name}" Loaded="nameEdit_Loaded" KeyDown="pulsarTeclaEnter"/>
            </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
    </DataGridTemplateColumn>

    En este codigo puedes ver que he implementado para esta plantilla, el evento "Loaded" en el TextBox, este evento hay que añadirlo a cada TextBox de la plantilla que quieras editar.

    Luego en el codigo cs, defines el evento de la siguiente forma:

            private void nameEdit_Loaded(object sender, RoutedEventArgs e)
            {
                // guardar referencia al TextBox correspondiente
                m_listTextBox.Add((TextBox)e.OriginalSource);
            }

    en este evento se van guardando las referencias a los TextBox creados en una lista.

    m_listTextBox es una variable privada en la clase definida de la siguiente forma:

            /// <summary>
            /// Lista para guardar las referencias a los textBoxs
            /// </summary>
            private List<TextBox> m_listTextBox = new List<TextBox>();

    y de este modo ya tienes todas las referencias a los TextBox en la lista añadidos por orden de celdas en el grid, de modo que la definicion del evento 'KeyDown' puede ser algo como esto:

            private void pulsarTeclaEnter(object sender, KeyEventArgs e)
            {
    
                if ((e.Key == Key.Enter || e.Key == Key.Return) && e.Source.GetType() == typeof(TextBox))
                {
                    // obtener el textbox actual
                    TextBox text = (TextBox)e.OriginalSource;
                    // evento manejado
                    e.Handled = true;    
                
                    // obtener el indice del siguiente textBox en la lista (actual + 1)
                    int index = m_listTextBox.IndexOf(text) + 1;
    
                    // ver si esta dentro de los limites y se establece el foco en el siguiente TextBox
                    if (index < m_listTextBox.Count)
                        ((TextBox)m_listTextBox.ElementAt(index)).Focus();
                    // mover el foco al siguiente control (se han acabado los TextBox del grid)
                    else                 
                        text.MoveFocus(new TraversalRequest(FocusNavigationDirection.Down));
                }
            }

    y cada vez que pulses la tecla 'intro' se ira poniendo el foco en el siguiente TextBox de la lista.

    De la forma que lo tienes, esta es posiblemente la forma mas sencilla de realizarlo.

     


    Saludos
    David González
    • Marcado como respuesta WpfSoft domingo, 4 de abril de 2010 9:29
    sábado, 3 de abril de 2010 21:51

Todas las respuestas

  • Hola WpfSoft.

    Como son plantillas no puedes acceder a los elementos visuales por los medios tradicionales.

    la forma mas facil que tienes para cambiar focos, es guardando las referencias a los TextBox en el orden que se vayan creando y de paso te servira para ir pasando de uno a otro en el orden que los vayas insertando en la lista, que por defecto sera en orden de celdas.

    para realizar esto, puedes hacer algo como lo siguiente:

    codigo xaml de las plantillas con los texBox:

    <DataGridTemplateColumn Header="nombre" Width="70">
        <DataGridTemplateColumn.CellTemplate>
            <DataTemplate>
                <TextBox Text="{Binding Mode=TwoWay, Path=name}" Loaded="nameEdit_Loaded" KeyDown="pulsarTeclaEnter"/>
            </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
    </DataGridTemplateColumn>

    En este codigo puedes ver que he implementado para esta plantilla, el evento "Loaded" en el TextBox, este evento hay que añadirlo a cada TextBox de la plantilla que quieras editar.

    Luego en el codigo cs, defines el evento de la siguiente forma:

            private void nameEdit_Loaded(object sender, RoutedEventArgs e)
            {
                // guardar referencia al TextBox correspondiente
                m_listTextBox.Add((TextBox)e.OriginalSource);
            }

    en este evento se van guardando las referencias a los TextBox creados en una lista.

    m_listTextBox es una variable privada en la clase definida de la siguiente forma:

            /// <summary>
            /// Lista para guardar las referencias a los textBoxs
            /// </summary>
            private List<TextBox> m_listTextBox = new List<TextBox>();

    y de este modo ya tienes todas las referencias a los TextBox en la lista añadidos por orden de celdas en el grid, de modo que la definicion del evento 'KeyDown' puede ser algo como esto:

            private void pulsarTeclaEnter(object sender, KeyEventArgs e)
            {
    
                if ((e.Key == Key.Enter || e.Key == Key.Return) && e.Source.GetType() == typeof(TextBox))
                {
                    // obtener el textbox actual
                    TextBox text = (TextBox)e.OriginalSource;
                    // evento manejado
                    e.Handled = true;    
                
                    // obtener el indice del siguiente textBox en la lista (actual + 1)
                    int index = m_listTextBox.IndexOf(text) + 1;
    
                    // ver si esta dentro de los limites y se establece el foco en el siguiente TextBox
                    if (index < m_listTextBox.Count)
                        ((TextBox)m_listTextBox.ElementAt(index)).Focus();
                    // mover el foco al siguiente control (se han acabado los TextBox del grid)
                    else                 
                        text.MoveFocus(new TraversalRequest(FocusNavigationDirection.Down));
                }
            }

    y cada vez que pulses la tecla 'intro' se ira poniendo el foco en el siguiente TextBox de la lista.

    De la forma que lo tienes, esta es posiblemente la forma mas sencilla de realizarlo.

     


    Saludos
    David González
    • Marcado como respuesta WpfSoft domingo, 4 de abril de 2010 9:29
    sábado, 3 de abril de 2010 21:51
  • Muchas gracias David por tus respuestas, voy a implementar tus ejemplos.
    domingo, 4 de abril de 2010 9:27
  • Buen Dia

    quisiera saber como ubicarme en una celda del datagrid pero sin crear TextBox en la grilla

     

    Gracias


    Luis Alejandro Duarte
    viernes, 17 de diciembre de 2010 15:54