Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Linq;
- using System.Windows;
- using System.Windows.Controls;
- using System.Windows.Data;
- using System.Windows.Documents;
- using System.Windows.Media;
- namespace MyApp.Extensions
- {
- /// <summary>
- /// Extension add/remove a watermark to a textbox
- /// <remarks>
- /// //Add namespace to xaml - xmlns:ext="clr-namespace:MyApp.Extensions"
- /// <TextBox ext:Watermark.Text="Your Watermark Goes Here"/>
- /// </remarks>
- /// </summary>
- public static class Watermark
- {
- public static readonly DependencyProperty TextProperty =
- DependencyProperty.RegisterAttached("Text", typeof(string), typeof(Watermark), new PropertyMetadata(new PropertyChangedCallback(OnTextChanged)));
- public static string GetText(DependencyObject obj)
- {
- return (string)obj.GetValue(TextProperty);
- }
- public static void SetText(DependencyObject obj, string value)
- {
- obj.SetValue(TextProperty, value);
- }
- static void OnTextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
- {
- var control = d as TextBox;
- if (control == null)
- return;
- if (e.OldValue != null)
- {
- control.Loaded -= control_Loaded;
- control.GotFocus -= control_GotFocus;
- control.LostFocus -= control_LostFocus;
- control.TextChanged -= control_TextChanged;
- }
- if (e.NewValue != null)
- {
- control.Loaded += control_Loaded;
- control.GotFocus += control_GotFocus;
- control.LostFocus += control_LostFocus;
- control.TextChanged += control_TextChanged;
- }
- }
- static void control_Loaded(object sender, RoutedEventArgs e)
- {
- var control = sender as TextBox;
- if (control == null)
- return;
- if (string.IsNullOrWhiteSpace(control.Text))
- AddWatermark(control);
- }
- static void control_GotFocus(object sender, RoutedEventArgs e)
- {
- var control = sender as TextBox;
- if (control == null)
- return;
- RemoveWatermark(control);
- }
- static void control_LostFocus(object sender, RoutedEventArgs e)
- {
- var control = sender as TextBox;
- if (control == null)
- return;
- if (string.IsNullOrWhiteSpace(control.Text))
- AddWatermark(control);
- }
- static void control_TextChanged(object sender, TextChangedEventArgs e)
- {
- var control = sender as TextBox;
- if (control == null)
- return;
- if (string.IsNullOrWhiteSpace(control.Text) && !control.IsKeyboardFocusWithin)
- AddWatermark(control);
- else
- RemoveWatermark(control);
- }
- /// <summary>
- /// Show the watermark on the specified control
- /// </summary>
- /// <param name="control">Control to show the watermark on</param>
- static void AddWatermark(Control control)
- {
- AdornerLayer layer = AdornerLayer.GetAdornerLayer(control);
- // layer could be null if control is no longer in the visual tree
- if (layer != null)
- {
- //check to see if control already has an adorner
- Adorner[] adorners = layer.GetAdorners(control);
- if (adorners != null)
- {
- foreach (Adorner adorner in adorners)
- {
- if (adorner is WatermarkAdorner)
- return;
- }
- }
- layer.Add(new WatermarkAdorner(control, GetText(control)));
- }
- }
- /// <summary>
- /// Remove the watermark from the specified element
- /// </summary>
- /// <param name="control">Element to remove the watermark from</param>
- static void RemoveWatermark(UIElement control)
- {
- AdornerLayer layer = AdornerLayer.GetAdornerLayer(control);
- // layer could be null if control is no longer in the visual tree
- if (layer != null)
- {
- Adorner[] adorners = layer.GetAdorners(control);
- if (adorners == null)
- return;
- foreach (Adorner adorner in adorners)
- {
- if (adorner is WatermarkAdorner)
- {
- adorner.Visibility = Visibility.Hidden;
- layer.Remove(adorner);
- }
- }
- }
- }
- }
- /// <summary>
- /// Adorner for the watermark
- /// </summary>
- public class WatermarkAdorner : Adorner
- {
- #region Private Fields
- /// <summary>
- /// <see cref="ContentPresenter"/> that holds the watermark
- /// </summary>
- private readonly ContentPresenter contentPresenter;
- #endregion
- #region Constructor
- /// <summary>
- /// Initializes a new instance of the <see cref="WatermarkAdorner"/> class
- /// </summary>
- /// <param name="adornedElement"><see cref="UIElement"/> to be adorned</param>
- /// <param name="watermark">The watermark</param>
- public WatermarkAdorner(UIElement adornedElement, object watermark) :
- base(adornedElement)
- {
- this.IsHitTestVisible = false;
- this.contentPresenter = new ContentPresenter();
- this.contentPresenter.Content = watermark;
- this.contentPresenter.Opacity = 0.5;
- this.contentPresenter.Margin = new Thickness(Control.Margin.Left + Control.Padding.Left, Control.Margin.Top + Control.Padding.Top, 0, 0);
- if (this.Control is ItemsControl && !(this.Control is ComboBox))
- {
- this.contentPresenter.VerticalAlignment = VerticalAlignment.Center;
- this.contentPresenter.HorizontalAlignment = HorizontalAlignment.Center;
- }
- // Hide the control adorner when the adorned element is hidden
- Binding binding = new Binding("IsVisible");
- binding.Source = adornedElement;
- binding.Converter = new BooleanToVisibilityConverter();
- this.SetBinding(VisibilityProperty, binding);
- this.Margin = new Thickness(Control.Padding.Left, Control.Padding.Top, Control.Padding.Right, Control.Padding.Bottom);
- }
- #endregion
- #region Protected Properties
- /// <summary>
- /// Gets the number of children for the <see cref="ContainerVisual"/>.
- /// </summary>
- protected override int VisualChildrenCount
- {
- get { return 1; }
- }
- #endregion
- #region Private Properties
- /// <summary>
- /// Gets the control that is being adorned
- /// </summary>
- private Control Control
- {
- get { return (Control)this.AdornedElement; }
- }
- #endregion
- #region Protected Overrides
- /// <summary>
- /// Returns a specified child <see cref="Visual"/> for the parent <see cref="ContainerVisual"/>.
- /// </summary>
- /// <param name="index">A 32-bit signed integer that represents the index value of the child <see cref="Visual"/>. The value of index must be between 0 and <see cref="VisualChildrenCount"/> - 1.</param>
- /// <returns>The child <see cref="Visual"/>.</returns>
- protected override Visual GetVisualChild(int index)
- {
- return this.contentPresenter;
- }
- /// <summary>
- /// Implements any custom measuring behavior for the adorner.
- /// </summary>
- /// <param name="constraint">A size to constrain the adorner to.</param>
- /// <returns>A <see cref="Size"/> object representing the amount of layout space needed by the adorner.</returns>
- protected override Size MeasureOverride(Size constraint)
- {
- // Here's the secret to getting the adorner to cover the whole control
- this.contentPresenter.Measure(Control.RenderSize);
- return Control.RenderSize;
- }
- /// <summary>
- /// When overridden in a derived class, positions child elements and determines a size for a <see cref="FrameworkElement"/> derived class.
- /// </summary>
- /// <param name="finalSize">The final area within the parent that this element should use to arrange itself and its children.</param>
- /// <returns>The actual size used.</returns>
- protected override Size ArrangeOverride(Size finalSize)
- {
- this.contentPresenter.Arrange(new Rect(finalSize));
- return finalSize;
- }
- #endregion
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment