Los textbox con watermark o “marca de agua” son un control muy común en casi cualquier sitio, y por alguna razón Silverlight 4 no viene ya con un control de este tipo, aunque el textbox si tiene una propiedad que se llama Watermark, no se puede usar…

Así que aquí les dejo un textbox con watermark que realizé para un proyecto (el cual pueden descargar al final del artículo o probarlo aquí), fué también mi primer Custom Control en Silverlight, así que cualquier comentario o correción son muy bienvenidos.

El código fuente es el siguiente, cómo se puede ver, el control cuenta con sólo dos propiedades, una para modificar el texto del watermark y otra para cambiar la fuente del watermark:


/// <summary>
    /// A TextBox control with a watermark
    /// </summary>

    [TemplatePart(Name = WatermarkedTextbox.watermarkTextBlock, Type = typeof(TextBlock))]
    public class WatermarkedTextbox : TextBox
    {

        #region Constants
        private const string watermarkTextBlock = "PART_Watermark";
        #endregion

        #region Properties

        public static readonly DependencyProperty Watermark_Property = DependencyProperty.Register("Watermark_", typeof(string), typeof(WatermarkedTextbox),
            new PropertyMetadata("watermark"));

        public static readonly DependencyProperty WatermarkFontFamilyProperty = DependencyProperty.Register(
            "WatermarkFontStyle", typeof(FontFamily), typeof(WatermarkedTextbox),
            new PropertyMetadata(new FontFamily("Segoe Print")));

        /// <summary>
        /// Gets or sets the text for the watermark
        /// </summary>
        [Category("Watermark")]
        [Description("Gets or sets the text for the watermark")]
        public string Watermark_
        {
            get { return (string)GetValue(Watermark_Property); }
            set { SetValue(Watermark_Property, value); }
        }

        /// <summary>
        /// Gets or sets the fontfamily for the watermark
        /// </summary>
        [Category("Watermark")]
        [Description("Gets or sets the text font for the watermark")]
        public FontFamily WatermarkFontFamily
        {
            get { return (FontFamily)GetValue(WatermarkFontFamilyProperty); }
            set { SetValue(WatermarkFontFamilyProperty, value); }
        }

        #endregion

        private Boolean watermarked;

        public WatermarkedTextbox()
        {
            DefaultStyleKey = typeof(WatermarkedTextbox);
            watermarked = true;
            this.GotFocus += new RoutedEventHandler(WatermarkedTextbox_GotFocus);
            this.LostFocus += new RoutedEventHandler(WatermarkedTextbox_LostFocus);
            this.IsEnabledChanged += new DependencyPropertyChangedEventHandler(WatermarkedTextbox_IsEnabledChanged);
            this.TextChanged += new TextChangedEventHandler(WatermarkedTextbox_TextChanged);
        }

        void WatermarkedTextbox_TextChanged(object sender, TextChangedEventArgs e)
        {
            if (watermarked)
                Unwatermark();
            if (this.Text == string.Empty)
                Watermark();
        }

        void WatermarkedTextbox_IsEnabledChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            if (IsEnabled)
                GotoVisualState(WatermarkedTextboxVisualStates.Normal, true);
            else
                GotoVisualState(WatermarkedTextboxVisualStates.Disabled, true);
        }

        void WatermarkedTextbox_LostFocus(object sender, RoutedEventArgs e)
        {
            if (this.Text == string.Empty)
                Watermark();
        }

        void WatermarkedTextbox_GotFocus(object sender, RoutedEventArgs e)
        {
            if (this.Text == string.Empty)
                Unwatermark();
            else
                this.SelectAll();
        }

        private void GotoVisualState(WatermarkedTextboxVisualStates VisualState, bool useTransitions)
        {
            VisualStateManager.GoToState(this, VisualState.ToString(), useTransitions);
        }

        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();

            if (this.Text != string.Empty)
                Unwatermark();
        }

        private void Watermark()
        {
            GotoVisualState(WatermarkedTextboxVisualStates.Watermarked, false);
            watermarked = true;
        }

        private void Unwatermark()
        {
            GotoVisualState(WatermarkedTextboxVisualStates.Unwatermarked, false);
            watermarked = false;
        }
    }
    public enum WatermarkedTextboxVisualStates { Normal, Disabled, Watermarked, Unwatermarked }

 

Descarga el control completo aquí o pruébalo aquí

Ok, this is my very first post in English and it will be very short, I just hope’s that it helps you to understand a new way to use the data binding.

What will we do?

I will use a VERY simple application to show how you can bind a property of an object to another object, binding the length of the text in a TextBox to the text in a TextBlock. So that the TextBlock will show the number of characters in the TextBox automatically as you type. You can see the functional sample here

The application only has two controls: a TextBox and a TextBlock:

image

The XAML for that goes like this:

<Grid Background="White">
    	<TextBlock Margin="0,0,14,8" VerticalAlignment="Bottom" Height="32" Text="{Binding Text.Length, ElementName=theText}" TextWrapping="Wrap" FontSize="24" HorizontalAlignment="Right" Width="124" Foreground="#FF767474" TextAlignment="Right"/>
    	<TextBox Margin="17,8,14,8" x:Name="theText" Text="TextBox" TextWrapping="Wrap" FontSize="24" Background="{x:Null}" BorderBrush="Black"/>
    </Grid>

As you can see, we have assigned a Name to the TextBox, this is important because we need to tell the Binding from where to get the values. Now to the interesting part, the binding:

Set the TextBlock text value to {Binding Text.Length, ElementName=theText}, so you have something like this:

<TextBlock Margin="0,0,14,8" VerticalAlignment="Bottom" Height="32" Text="{Binding Text.Length, ElementName=theText}" TextWrapping="Wrap" FontSize="24" HorizontalAlignment="Right" Width="124" Foreground="#FF767474" TextAlignment="Right"/>

With this, we have already finished the sample application,  if you run it, you will see a control like this one:

image

Binding is a very powerful tool that can be used in many ways and that can save a lot of work, like in the sample above; Binding allowed us to set an “interaction” betwenn two objects without having to write any code at all.

image

Bing Maps Platform es una plataforma de Microsoft que permite desarrollar aplicaciones utilizando las funciones de Bing Maps. Se puede desarrollar para esta plataforma con AJAX o con Silverlight utilizando sus respectivos SDK’s. Cada uno tiene sus diferentes capacidades, aquí daremos el primer paso con el SDK de Silverlight desarrollando una pequeña aplicación que muestre al mapa del mundo en vista “Aerial” y las etiquetas de cada lugar del mapa.

El primer paso es ir al bingmapsportal y registrar una cuenta para que se te proporcione una credencial con la que puedas acceder al servicio.

Después de obtener la credencial, el paso que sigue es bajar e instalar el “Bing Maps Silverlight Control SDK” el cual puedes bajar desde aquí.

Ya que instalaste el SDK en tu computadora, puedes empezar a desarrollar tu primera aplicación con Bing Maps:

  1. Crea un proyecto de Silverlight en Visual Studio 2008 o superior (para este tutorial estoy suponiendo que ya se cuenta con Visual Studio y Silverlight instalado, en caso de que no cuentes con una version nueva de Visual Studio y seas un estudiante, puedes conseguirlo de manera gratuita y oficialemte gracias a Dreamspark)
  2. Cuando te pregunte, marca la opción de hostear la aplicación en un nuevo sitio Web.image
  3. El siguiente paso es referenciar las librerias que acabas de instalar a tu proyecto, da click derecho en folder de “References” del proyecto de Silverlight y selecciona “Add Reference”  Add Reference
  4. Selecciona la pestaña de Browse y navega al directorio donde instalaste el Silverlight Control SDK (normalmente debe ser algo como C:\Program Files\Bing Maps Silverlight Control\V1\Libraries). Selecciona las librerias y da click en “OK”image
  5. Agrega el control a tu proyecto creando un namespace en la clase principal. Dentro del tag UserControl teclea la siguiente línea:
    xmlns:m="clr-namespace:Microsoft.Maps.MapControl;assembly=Microsoft.Maps.MapControl";
    
  6. Ahora sólo queda insertar al mapa, dentro de la etiqueta Grid agrega al elemento Map y dale la credencial que obtuviste al crear tu cuenta en Bing Maps:
    <Grid x:Name="LayoutRoot" Background="White">
       <m:Map CredentialsProvider="aqui va la credencial">
    
       </m:Map>
    </Grid>
    

    Si corres el programa en este punto obtendrás algo como lo siguiente:image

  7. Ya cuentas con un mapa completamente funcional pero que inicia por default con la vista Road. Para especificar como quieres que inicie puedes modificar los atributos de Map haciendo algo como lo
    siguiente:

    <Grid x:Name="LayoutRoot" Background="White">
          <m:Map  CredentialsProvider="credencial"
                      Mode="AerialwithLabels"
                      ScaleVisibility="Collapsed"
                     NavigationVisibility="Collapsed">
          </m:Map>
    </Grid>

Mode está especificando cuál será la vista inicial, y las otras dos instrucciones estan escondiendo los controles, de manera que al final se ve así:

Y eso es todo. Empezar a desarrollar con esta plaraforma es muy sencillo y se pueden hacer cosas bastante interesantes.Para conocer con más profundidad lo que se puede hacer con Bing Maps de manera rápida puedes visitar el Silverlight Interactive SDK.