none
DatePicker - No responde al IsDefault, cuando se presiona Enter RRS feed

  • Pregunta

  • hola

    Tengo varios TextBox que al tener el foco y presionar Enter, lanzan la el comando definido en el boton, el cual tiene la propiedad IsDefault en true, para lograrlo.

    <Button Command="{Binding Path=SearchCommand}" Content="{x:Static Member=res:Labels.Search}" HorizontalAlignment="Center" Margin="5" IsDefault="True" />

    El problema se me presenta con el DatePicker, el cual al tener el foco, y escribir una fecha valida, si se presionar enter no lanza el commando de busqueda.

    Estaba probando usar:

    <DatePicker SelectedDate="{Binding Path=DateOfBirth}" >
        <DatePicker.InputBindings>
            <KeyBinding Key="Enter" Command="{Binding SearchCommand}" />
        </DatePicker.InputBindings>
    </DatePicker>

    pero no ha funcionado

    Entiendo que se debe a que el Enter en este control es usado de una forma diferentes, pero saben si hay forma de lanzar el comando?

    Estoy usando VS2010 y MVVM, por lo cual tendrias que resolve el problema usando xaml, no tengo code-behind donde tomar algun evento del DatePicker

    saludos

     


    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina
    jueves, 4 de noviembre de 2010 21:36

Respuestas

  • Hola Leandro

    No se si has resuelto esto.

    El problema es que el DatePicker es un control compuesto internamente por un textbox para escribir y teniendo el foco en el textbox el enter lo está capturando este y no el datepicker, con cualquier otra tecla funciona correctamente.

    Solución, he hecho una copia del template standard y al textbox internamente le he añadido el keybinding.... esta claro que si lo quieres usar en muchos datepicker es una chapuza el tener el controltemplate de cada uno editado solo para ejecutar un keybinding, la otra solución sería hacerte un control personalizado de datepicker al que le añadieses una dependency property de tipo ICommand que luego pudieses heredar en la plantilla y hacer una plantilla generica.

    Te dejo el xaml de la plantilla modificada que ejecuta el comando, busca el Datepickertextbox "PART_TextBox":

        								<DatePickerTextBox x:Name="PART_TextBox" Grid.Column="0" Foreground="{TemplateBinding Foreground}" Focusable="{TemplateBinding Focusable}" HorizontalContentAlignment="Stretch" Grid.Row="0" VerticalContentAlignment="Stretch">
        									<DatePickerTextBox.InputBindings>
        										<KeyBinding Key="Enter" Command="{Binding GotoNextPageCommand}"></KeyBinding>
    											</DatePickerTextBox.InputBindings>						
    										</DatePickerTextBox>
    

    Esto más que una solución es una idea de por donde van los tiros, espero que te sirva de base para llegar a una solución menos "chapucera"

    Un gran saludo compañero!


    MCTS .NET Framework 3.5 Windows Forms Application Development
    MCTS .NET Framework 3.5 Windows Presentation Foundation
    Visita mi Blog en Geeks.ms
    Sigueme en Twitter
    viernes, 12 de noviembre de 2010 11:41
    Moderador
  • hola Josue

    disculpa por la tardanza en la repuesta, resulta que no estaba directamente con el tema, solo me habia consultado

    resulto al final que con un control, como habias comentado, personalziado se pudo resolver

    basicamente se busco el control compuesto, o sea el textbox que forma el DatePicker y a este se le adjunto el evento keydown para poder anular el enter

     

        public class DatePickerCustom : DatePicker
        {
            protected override void OnRender(System.Windows.Media.DrawingContext drawingContext)
            {
                DatePickerTextBox raw = RawDatePickerTextBox;
                if (raw != null)
                {
                    raw.AddHandler(KeyDownEvent, new KeyEventHandler(OnKeyDown), true);
                    base.OnRender(drawingContext);
                }
               
            }

            private static void OnKeyDown(object sender, KeyEventArgs e)
            {
                if (e.Key == Key.Enter)
                    e.Handled = false;
            }

            private DatePickerTextBox RawDatePickerTextBox
            {
                get
                {
                    return FindFirstChild<DatePickerTextBox>(this);
                }
            }
           
            public static T FindFirstChild<T>(DependencyObject depObj) where T : DependencyObject
            {
                if (depObj == null) return null;

                if (depObj is T && depObj is FrameworkElement)
                    return depObj as T;

                for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
                {
                    DependencyObject child = VisualTreeHelper.GetChild(depObj, i);

                    T obj = FindFirstChild<T>(child);

                    if (obj != null)
                        return obj;
                }

                return null;
            }
           
        }

    en realidad el FindFirstChild n o forma parte del control, lo puse para no tener que copiar el codigo completo de un UIHelper que ayuda en la busqueda de controles

    saludos

     


    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina
    lunes, 29 de noviembre de 2010 13:48

Todas las respuestas

  • Hola Leandro

    No se si has resuelto esto.

    El problema es que el DatePicker es un control compuesto internamente por un textbox para escribir y teniendo el foco en el textbox el enter lo está capturando este y no el datepicker, con cualquier otra tecla funciona correctamente.

    Solución, he hecho una copia del template standard y al textbox internamente le he añadido el keybinding.... esta claro que si lo quieres usar en muchos datepicker es una chapuza el tener el controltemplate de cada uno editado solo para ejecutar un keybinding, la otra solución sería hacerte un control personalizado de datepicker al que le añadieses una dependency property de tipo ICommand que luego pudieses heredar en la plantilla y hacer una plantilla generica.

    Te dejo el xaml de la plantilla modificada que ejecuta el comando, busca el Datepickertextbox "PART_TextBox":

        								<DatePickerTextBox x:Name="PART_TextBox" Grid.Column="0" Foreground="{TemplateBinding Foreground}" Focusable="{TemplateBinding Focusable}" HorizontalContentAlignment="Stretch" Grid.Row="0" VerticalContentAlignment="Stretch">
        									<DatePickerTextBox.InputBindings>
        										<KeyBinding Key="Enter" Command="{Binding GotoNextPageCommand}"></KeyBinding>
    											</DatePickerTextBox.InputBindings>						
    										</DatePickerTextBox>
    

    Esto más que una solución es una idea de por donde van los tiros, espero que te sirva de base para llegar a una solución menos "chapucera"

    Un gran saludo compañero!


    MCTS .NET Framework 3.5 Windows Forms Application Development
    MCTS .NET Framework 3.5 Windows Presentation Foundation
    Visita mi Blog en Geeks.ms
    Sigueme en Twitter
    viernes, 12 de noviembre de 2010 11:41
    Moderador
  • hola Josue

    disculpa por la tardanza en la repuesta, resulta que no estaba directamente con el tema, solo me habia consultado

    resulto al final que con un control, como habias comentado, personalziado se pudo resolver

    basicamente se busco el control compuesto, o sea el textbox que forma el DatePicker y a este se le adjunto el evento keydown para poder anular el enter

     

        public class DatePickerCustom : DatePicker
        {
            protected override void OnRender(System.Windows.Media.DrawingContext drawingContext)
            {
                DatePickerTextBox raw = RawDatePickerTextBox;
                if (raw != null)
                {
                    raw.AddHandler(KeyDownEvent, new KeyEventHandler(OnKeyDown), true);
                    base.OnRender(drawingContext);
                }
               
            }

            private static void OnKeyDown(object sender, KeyEventArgs e)
            {
                if (e.Key == Key.Enter)
                    e.Handled = false;
            }

            private DatePickerTextBox RawDatePickerTextBox
            {
                get
                {
                    return FindFirstChild<DatePickerTextBox>(this);
                }
            }
           
            public static T FindFirstChild<T>(DependencyObject depObj) where T : DependencyObject
            {
                if (depObj == null) return null;

                if (depObj is T && depObj is FrameworkElement)
                    return depObj as T;

                for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
                {
                    DependencyObject child = VisualTreeHelper.GetChild(depObj, i);

                    T obj = FindFirstChild<T>(child);

                    if (obj != null)
                        return obj;
                }

                return null;
            }
           
        }

    en realidad el FindFirstChild n o forma parte del control, lo puse para no tener que copiar el codigo completo de un UIHelper que ayuda en la busqueda de controles

    saludos

     


    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina
    lunes, 29 de noviembre de 2010 13:48