167 lines
3.9 KiB
C#
167 lines
3.9 KiB
C#
|
|
using System;
|
||
|
|
using System.Collections.Generic;
|
||
|
|
using System.Windows;
|
||
|
|
using System.Windows.Controls;
|
||
|
|
using System.Windows.Controls.Primitives;
|
||
|
|
using System.Windows.Documents;
|
||
|
|
|
||
|
|
namespace UnicodeCharacterInspector
|
||
|
|
{
|
||
|
|
// Inspired by http://stackoverflow.com/questions/833943/watermark-hint-text-placeholder-textbox-in-wpf
|
||
|
|
internal static partial class Placeholder
|
||
|
|
{
|
||
|
|
public static string GetText(DependencyObject obj)
|
||
|
|
{
|
||
|
|
return (string)obj.GetValue(TextProperty);
|
||
|
|
}
|
||
|
|
|
||
|
|
public static void SetText(DependencyObject obj, string value)
|
||
|
|
{
|
||
|
|
obj.SetValue(TextProperty, value);
|
||
|
|
}
|
||
|
|
|
||
|
|
public static readonly DependencyProperty TextProperty = DependencyProperty.RegisterAttached("Text", typeof(string), typeof(Placeholder), new PropertyMetadata(OnTextChanged));
|
||
|
|
|
||
|
|
private static readonly HashSet<Control> handledControls = new HashSet<Control>();
|
||
|
|
|
||
|
|
private static void OnTextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||
|
|
{
|
||
|
|
var control = d as TextBoxBase;
|
||
|
|
|
||
|
|
if (d == null) return;
|
||
|
|
|
||
|
|
if (e.NewValue == null || "".Equals(e.NewValue)) UnregisterControl(control);
|
||
|
|
else UpdateControl(control, (string)e.NewValue);
|
||
|
|
}
|
||
|
|
|
||
|
|
private static void OnControlLoaded(object sender, RoutedEventArgs e)
|
||
|
|
{
|
||
|
|
var control = (Control)sender;
|
||
|
|
UpdateControl(control, GetText(control));
|
||
|
|
}
|
||
|
|
|
||
|
|
private static void OnTextBoxGotKeyboardFocus(object sender, System.Windows.Input.KeyboardFocusChangedEventArgs e)
|
||
|
|
{
|
||
|
|
var control = (Control)sender;
|
||
|
|
RemoveAdorner(control);
|
||
|
|
}
|
||
|
|
|
||
|
|
private static void UpdateControl(Control control, string placeholderText)
|
||
|
|
{
|
||
|
|
if (handledControls.Add(control))
|
||
|
|
{
|
||
|
|
RegisterControl(control);
|
||
|
|
}
|
||
|
|
|
||
|
|
if (IsEmpty(control))
|
||
|
|
{
|
||
|
|
var adorner = GetAdorner(control) ?? AddAdorner(control);
|
||
|
|
if (adorner != null) adorner.Text = placeholderText;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
RemoveAdorner(control);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
private static void RegisterControl(Control control)
|
||
|
|
{
|
||
|
|
control.Loaded += OnControlLoaded;
|
||
|
|
|
||
|
|
var textBox = control as TextBoxBase;
|
||
|
|
if (textBox != null) RegisterTextBox(textBox);
|
||
|
|
}
|
||
|
|
|
||
|
|
private static void RegisterTextBox(TextBoxBase textBox)
|
||
|
|
{
|
||
|
|
textBox.GotKeyboardFocus += OnTextBoxGotKeyboardFocus;
|
||
|
|
textBox.LostKeyboardFocus += OnControlLoaded;
|
||
|
|
}
|
||
|
|
|
||
|
|
private static void UnregisterControl(Control control)
|
||
|
|
{
|
||
|
|
if (handledControls.Remove(control))
|
||
|
|
{
|
||
|
|
control.Loaded -= OnControlLoaded;
|
||
|
|
|
||
|
|
var textBox = control as TextBoxBase;
|
||
|
|
if (textBox != null) UnregisterTextBox(textBox);
|
||
|
|
|
||
|
|
RemoveAdorner(control);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
private static void UnregisterTextBox(TextBoxBase textBox)
|
||
|
|
{
|
||
|
|
textBox.GotKeyboardFocus -= OnTextBoxGotKeyboardFocus;
|
||
|
|
textBox.LostKeyboardFocus -= OnControlLoaded;
|
||
|
|
}
|
||
|
|
|
||
|
|
private static bool IsEmpty(Control control)
|
||
|
|
{
|
||
|
|
var textBox = control as TextBox;
|
||
|
|
|
||
|
|
if (textBox != null) return string.IsNullOrEmpty(textBox.Text);
|
||
|
|
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
private static PlaceholderAdorner GetAdorner(Control control)
|
||
|
|
{
|
||
|
|
var layer = AdornerLayer.GetAdornerLayer(control);
|
||
|
|
|
||
|
|
if (layer != null)
|
||
|
|
{
|
||
|
|
var adorners = layer.GetAdorners(control);
|
||
|
|
|
||
|
|
if (adorners != null)
|
||
|
|
{
|
||
|
|
foreach (var adorner in adorners)
|
||
|
|
{
|
||
|
|
var placeholder = adorner as PlaceholderAdorner;
|
||
|
|
|
||
|
|
if (placeholder != null) return placeholder;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
|
||
|
|
private static PlaceholderAdorner AddAdorner(Control control)
|
||
|
|
{
|
||
|
|
var layer = AdornerLayer.GetAdornerLayer(control);
|
||
|
|
|
||
|
|
if (layer == null) return null;
|
||
|
|
|
||
|
|
var placeholder = new PlaceholderAdorner(control);
|
||
|
|
|
||
|
|
layer.Add(placeholder);
|
||
|
|
|
||
|
|
return placeholder;
|
||
|
|
}
|
||
|
|
|
||
|
|
private static void RemoveAdorner(Control control)
|
||
|
|
{
|
||
|
|
var layer = AdornerLayer.GetAdornerLayer(control);
|
||
|
|
|
||
|
|
if (layer == null) return;
|
||
|
|
|
||
|
|
var adorners = layer.GetAdorners(control);
|
||
|
|
|
||
|
|
if (adorners == null) return;
|
||
|
|
|
||
|
|
foreach (var adorner in adorners)
|
||
|
|
{
|
||
|
|
var placeholder = adorner as PlaceholderAdorner;
|
||
|
|
|
||
|
|
if (placeholder != null)
|
||
|
|
{
|
||
|
|
layer.Remove(placeholder);
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|