none
Tooltip Datepicker RRS feed

  • Pregunta

  • Hola de nuevo! Me gustaría saber si se le pueden poner tooltips a los dias de un DatePicker. Al estar tachando algunos dias (las fiestas) me gustaría poder poner en un tooltip el nombre de la fiesta. Gracias
    alex
    viernes, 14 de mayo de 2010 11:46

Respuestas

  • Hola de nuevo fernialex.

    Tienes razon, en silverlight no funciona ese evento al estar abierto el panel.

    Asi, que vamos a entrar mas en la plantilla, no he tenido mucho tiempo, asi que dejo esto que funciona medianamente bien, aunque hay que pulirlo ya que no va muy fino lo de llegar hasta el 'CalendarDayButton'.

     

    Primero modificamos la plantilla del DatePicker para añadir el evento 'MouseMove' directamente en la plantilla del calendar, de forma que se nos queda un estilo como el siguiente (estilo clonado, solo se ha añadido el evento)

     

     

    		<Style x:Key="CalendarStyle1" TargetType="controls:Calendar">
    			<Setter Property="IsTabStop" Value="False"/>
    			<Setter Property="Background">
    				<Setter.Value>
    					<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
    						<GradientStop Color="#FFD3DEE8" Offset="0"/>
    						<GradientStop Color="#FFD3DEE8" Offset="0.16"/>
    						<GradientStop Color="#FFFCFCFD" Offset="0.16"/>
    						<GradientStop Color="#FFFFFFFF" Offset="1"/>
    					</LinearGradientBrush>
    				</Setter.Value>
    			</Setter>
    			<Setter Property="BorderThickness" Value="1"/>
    			<Setter Property="BorderBrush">
    				<Setter.Value>
    					<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
    						<GradientStop Color="#FFA3AEB9" Offset="0"/>
    						<GradientStop Color="#FF8399A9" Offset="0.375"/>
    						<GradientStop Color="#FF718597" Offset="0.375"/>
    						<GradientStop Color="#FF617584" Offset="1"/>
    					</LinearGradientBrush>
    				</Setter.Value>
    			</Setter>
    			<Setter Property="Template">
    				<Setter.Value>
    					<ControlTemplate TargetType="controls:Calendar">
    						<StackPanel x:Name="Root" HorizontalAlignment="Center">
    							<System_Windows_Controls_Primitives:CalendarItem x:Name="CalendarItem" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" MouseMove="CalendarItem_MouseMove"/>
    						</StackPanel>
    					</ControlTemplate>
    				</Setter.Value>
    			</Setter>
    		</Style>

     

    Bien, una vez definido el estilo, se aplica al DatePicker, de modo que quede de la siguiente forma:

     

    <controls:DatePicker Height="41" MouseMove="DatePicker_MouseMove" HorizontalAlignment="Left" Margin="153,176,0,0" VerticalAlignment="Top" Width="154" CalendarStyle="{StaticResource CalendarStyle1}"/>

     

     

    Los nombres de espacios usados son:

     

    	xmlns:controls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls"
    	xmlns:System_Windows_Controls_Primitives="clr-namespace:System.Windows.Controls.Primitives;assembly=System.Windows.Controls"

     

    Luego en el codigo .cs se controla el evento algo como lo siguiente:

     

      private void CalendarItem_MouseMove(object sender, System.Windows.Input.MouseEventArgs e)
      {
       
       if (((FrameworkElement)e.OriginalSource).Parent.GetType() == typeof(Grid))
       {
        Grid grid = (Grid)((FrameworkElement)e.OriginalSource).Parent;
        object control = VisualTreeHelper.GetParent(grid);    
    
        // en caso de ser un control de dia
        if (control.GetType() == typeof(System.Windows.Controls.Primitives.CalendarDayButton))
        {
         System.Windows.Controls.Primitives.CalendarDayButton day =
          (System.Windows.Controls.Primitives.CalendarDayButton)control;
    
         ToolTipService.SetToolTip(day, day.Content);
        }
       }
      }

     

     

    Y en un principio, se deberia de mostrar el dia en un toolTip, el pequeño problema es que, no siempre cae en la condicion del CalendarDayButton, no he tenido tiempo de ver el arbol visual para implementar esta funcion, pero lo dejo como  una forma de realizarlo. 

     

    Saludos
    David González
    martes, 25 de mayo de 2010 16:12

Todas las respuestas

  • Hola fernialex.

    ¿Como has puesto las aspas en los dias de vacaciones?. En caso de haber clonado el estilo, puedes hacer lo mismo para los toolTips.

    Puedes establecer un evento 'MouseMove' en el estilo ItemCalendar para obtener cada item y mostrar un tooltip.

    En cualquier otro caso, siempre puedes recorrer el arbol visual para obtener el calendarDayButton correspondiente y añadirle un ToolTip.

    Te pongo un ejemplo basico de esto ultimo y lo optimizas como desees:

    en el dataPicker, estableces un evento 'MouseMove' y en el codigo .cs del evento puedes poner algo como esto:

        private void DatePicker_MouseMove(object sender, MouseEventArgs e)
        {
          DatePicker date = (DatePicker)sender;
    
          if (date.IsDropDownOpen)
          {
            if (((FrameworkElement)e.OriginalSource).Parent == null) return;
            if (((FrameworkElement)e.OriginalSource).Parent.GetType() == typeof(Grid))
            {
              Grid grid = (Grid)((FrameworkElement)e.OriginalSource).Parent;
              object control = VisualTreeHelper.GetParent(grid);
    
              // en caso de ser un control de dia
              if (control.GetType() == typeof(System.Windows.Controls.Primitives.CalendarDayButton))
              {
                System.Windows.Controls.Primitives.CalendarDayButton day =
                  (System.Windows.Controls.Primitives.CalendarDayButton)control;
    
                day.ToolTip = day.Content;
              }
            }        
          }
        }

    Este ejemplo es una muestra y no he controlado posibles errores, se deberia de optimizar.

     

     

    Saludos
    David González
    lunes, 17 de mayo de 2010 14:45
  • los tipos calendarDayButton no tienen tooltip, lo acabo de mirar ahora mismo...

     

    day.ToolTip = day.Content; 

    no existe


    alex
    lunes, 17 de mayo de 2010 15:19
  • Hola Fernialex

    ¿Que framework estas usando?, el ejemplo es para .net 4.0 en WPF


    Saludos
    David González
    lunes, 17 de mayo de 2010 15:24
  • No, tengo el 3.5.....
    alex
    lunes, 17 de mayo de 2010 15:26
  • Hola fernialex.

    Si no tienes posibilidad de actualizartelo, te vas a tener que hacer tu el ToolTip para mostrar el valor.

    En el ejemplo de arriba explico como obtener el contenido del dia correspondiente, deberias de crearte un control de usuario que haga de toolTip al cual le puedas pasar el contenido y mostarlo en la posicion del raton.

     

    En el siguiente post, puse un ejemplo de como realizar una especie de toolbar flotante como la de office, puedes adaptarla eliminando elementos que no quieras para que haga de tooltip.

     


    Saludos
    David González
    lunes, 17 de mayo de 2010 16:01
  • Vale, muchas gracias, ya te contare a ver.
    alex
    martes, 18 de mayo de 2010 7:29
  • El codigo siguiente muestra lo que estoy haciendo para tachar unos dias en concreto. Cuando tacho el dia, ¿no hay ninguna posibilidad de ponerle un tooltip al dia tachado? Con el ToolTipService.SetTooltip lo intenté pero en principio nada... alguna idea? Intentar convertir el BlackOutDate en TextBlock, y asignarle el tooltip, nose...

    while (!fecha.Equals(new System.DateTime(System.DateTime.Today.Year + 2, 12, 1)))
                {
                    for (int i = 0; i < System.DateTime.DaysInMonth(fecha.Year, fecha.Month); i++)
                    {
                        if (cboSedes.SelectedIndex > 0)
                        {
                            //Aqui tachamos los dias
                            if (listFestivos.Where(f => f.Fecha == fecha.AddDays(i).Date).Count() > 0)
                            {
                                dpFRecepcion.BlackoutDates.Add(new CalendarDateRange(fecha.AddDays(i)));
                                dpDEnvio.BlackoutDates.Add(new CalendarDateRange(fecha.AddDays(i)));
                            }
                        }
                    }
                    //Pasamos al siguiente mes
                    fecha = fecha.AddMonths(1);
                }


    alex
    martes, 18 de mayo de 2010 9:42
  • Hola de nuevo fernialex.

    Tienes razon, no habia pensado en ToolTipService.

    te dejo el codigo adaptado para usar el datapicker de la WPF ToolKit para el framework 3.5 haciendo uso del ToolTipService:

        private void datePicker1_MouseMove(object sender, MouseEventArgs e)
        {
          Microsoft.Windows.Controls.DatePicker datePicker = (Microsoft.Windows.Controls.DatePicker)sender;
          
          if (datePicker.IsDropDownOpen)
          {
            if (((FrameworkElement)e.OriginalSource).Parent == null) return;
            if (((FrameworkElement)e.OriginalSource).Parent.GetType() == typeof(Grid))
            {
              Grid grid = (Grid)((FrameworkElement)e.OriginalSource).Parent;
              object control = VisualTreeHelper.GetParent(grid);
    
              // en caso de ser un control de dia
              if (control.GetType() == typeof(Microsoft.Windows.Controls.Primitives.CalendarDayButton))
              {
                Microsoft.Windows.Controls.Primitives.CalendarDayButton day =
                 (Microsoft.Windows.Controls.Primitives.CalendarDayButton)control;
    
                ToolTipService.SetToolTip(day, day.Content);
                //day.ToolTip = day.Content;
              }
            }
          }    
        }

    Como se puede observar es casi identico, solo cambia el namespace y se usa el objeto ToolTipService para mostrar el ToolTip.

     


    Saludos
    David González
    miércoles, 19 de mayo de 2010 15:37
  • Creo que no me vale ese evento. Cuando paso el raton x encima del datepicker entra en el evento, pero nunca entra en la primera condición. Cuando pincho en el calendario para desplegar los dias, ese evento no se genera.
    alex
    viernes, 21 de mayo de 2010 6:36
  • Hola fernialex.

    ¿Lo estas haciendo para WPF o silverligh?. Los ejemplos los he probado en WPF solamente.

    una cosa, este evento es para El dataPicker y se debe generar siempre con el calendario abierto o cerrado, de ahi que exista la condicion para ver si el calendario esta abierto con el 'isDroDownOpen'. 

     


    Saludos
    David González
    viernes, 21 de mayo de 2010 6:53
  • Lo estoy haciendo para Silverlight, pero lo que te digo, me entra en el evento cuando paso el raton por encima del datepicker cerrado nada mas.


    alex
    viernes, 21 de mayo de 2010 6:58
  • Hola de nuevo fernialex.

    Tienes razon, en silverlight no funciona ese evento al estar abierto el panel.

    Asi, que vamos a entrar mas en la plantilla, no he tenido mucho tiempo, asi que dejo esto que funciona medianamente bien, aunque hay que pulirlo ya que no va muy fino lo de llegar hasta el 'CalendarDayButton'.

     

    Primero modificamos la plantilla del DatePicker para añadir el evento 'MouseMove' directamente en la plantilla del calendar, de forma que se nos queda un estilo como el siguiente (estilo clonado, solo se ha añadido el evento)

     

     

    		<Style x:Key="CalendarStyle1" TargetType="controls:Calendar">
    			<Setter Property="IsTabStop" Value="False"/>
    			<Setter Property="Background">
    				<Setter.Value>
    					<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
    						<GradientStop Color="#FFD3DEE8" Offset="0"/>
    						<GradientStop Color="#FFD3DEE8" Offset="0.16"/>
    						<GradientStop Color="#FFFCFCFD" Offset="0.16"/>
    						<GradientStop Color="#FFFFFFFF" Offset="1"/>
    					</LinearGradientBrush>
    				</Setter.Value>
    			</Setter>
    			<Setter Property="BorderThickness" Value="1"/>
    			<Setter Property="BorderBrush">
    				<Setter.Value>
    					<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
    						<GradientStop Color="#FFA3AEB9" Offset="0"/>
    						<GradientStop Color="#FF8399A9" Offset="0.375"/>
    						<GradientStop Color="#FF718597" Offset="0.375"/>
    						<GradientStop Color="#FF617584" Offset="1"/>
    					</LinearGradientBrush>
    				</Setter.Value>
    			</Setter>
    			<Setter Property="Template">
    				<Setter.Value>
    					<ControlTemplate TargetType="controls:Calendar">
    						<StackPanel x:Name="Root" HorizontalAlignment="Center">
    							<System_Windows_Controls_Primitives:CalendarItem x:Name="CalendarItem" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" MouseMove="CalendarItem_MouseMove"/>
    						</StackPanel>
    					</ControlTemplate>
    				</Setter.Value>
    			</Setter>
    		</Style>

     

    Bien, una vez definido el estilo, se aplica al DatePicker, de modo que quede de la siguiente forma:

     

    <controls:DatePicker Height="41" MouseMove="DatePicker_MouseMove" HorizontalAlignment="Left" Margin="153,176,0,0" VerticalAlignment="Top" Width="154" CalendarStyle="{StaticResource CalendarStyle1}"/>

     

     

    Los nombres de espacios usados son:

     

    	xmlns:controls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls"
    	xmlns:System_Windows_Controls_Primitives="clr-namespace:System.Windows.Controls.Primitives;assembly=System.Windows.Controls"

     

    Luego en el codigo .cs se controla el evento algo como lo siguiente:

     

      private void CalendarItem_MouseMove(object sender, System.Windows.Input.MouseEventArgs e)
      {
       
       if (((FrameworkElement)e.OriginalSource).Parent.GetType() == typeof(Grid))
       {
        Grid grid = (Grid)((FrameworkElement)e.OriginalSource).Parent;
        object control = VisualTreeHelper.GetParent(grid);    
    
        // en caso de ser un control de dia
        if (control.GetType() == typeof(System.Windows.Controls.Primitives.CalendarDayButton))
        {
         System.Windows.Controls.Primitives.CalendarDayButton day =
          (System.Windows.Controls.Primitives.CalendarDayButton)control;
    
         ToolTipService.SetToolTip(day, day.Content);
        }
       }
      }

     

     

    Y en un principio, se deberia de mostrar el dia en un toolTip, el pequeño problema es que, no siempre cae en la condicion del CalendarDayButton, no he tenido tiempo de ver el arbol visual para implementar esta funcion, pero lo dejo como  una forma de realizarlo. 

     

    Saludos
    David González
    martes, 25 de mayo de 2010 16:12