[WPF系列]-高级部分 Shadowed TextBox

时间:2020-12-12 14:54:25

[WPF系列]-高级部分 Shadowed TextBox

Download Solution

ShadowedTextBoxExample.zip (70.3 KB)

Usage

<local:ShadowedTextBox Label="First Name" Text="{Binding FirstName}" />

Styles

<Style x:Key="shadowedLabelStyle">
<Setter Property="TextBlock.Foreground" Value="{x:Static SystemColors.ControlDarkBrush}" />
<Setter Property="FrameworkElement.Opacity" Value="0.8" />
<Setter Property="TextBlock.FontSize" Value="12" />
<Setter Property="TextBlock.FontStyle" Value="Italic" />
<Setter Property="TextBlock.Margin" Value="8,4,4,4" />
</Style> <Style TargetType="{x:Type local:ShadowedTextBox}">
<Setter Property="FontSize" Value="14" />
<Setter Property="Margin" Value="5,2,2,2" />
<Setter Property="LabelStyle" Value="{StaticResource shadowedLabelStyle}" />
</Style>

ShadowedTextBox.cs

using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents; namespace ShadowedTextBoxExample
{
public class ShadowedTextBox : TextBox
{
#region Properties
public string Label
{
get { return (string)GetValue(LabelProperty); }
set { SetValue(LabelProperty, value); }
} // Using a DependencyProperty as the backing store for Label. This enables animation, styling, binding, etc...
public static readonly DependencyProperty LabelProperty =
DependencyProperty.Register("Label", typeof(string), typeof(ShadowedTextBox), new UIPropertyMetadata("Label")); public Style LabelStyle
{
get { return (Style)GetValue(LabelStyleProperty); }
set { SetValue(LabelStyleProperty, value); }
} // Using a DependencyProperty as the backing store for LabelStyle. This enables animation, styling, binding, etc...
public static readonly DependencyProperty LabelStyleProperty =
DependencyProperty.Register("LabelStyle", typeof(Style), typeof(ShadowedTextBox), new UIPropertyMetadata(null)); public bool HasText
{
get { return (bool)GetValue(HasTextProperty); }
private set { SetValue(HasTextPropertyKey, value); }
} private static readonly DependencyPropertyKey HasTextPropertyKey =
DependencyProperty.RegisterReadOnly("HasText", typeof(bool), typeof(ShadowedTextBox), new PropertyMetadata(false));
public static readonly DependencyProperty HasTextProperty = HasTextPropertyKey.DependencyProperty; #endregion public ShadowedTextBox()
: base()
{
} AdornerLayer myAdornerLayer;
AdornerLabel myAdornerLabel;
public override void OnApplyTemplate()
{
base.OnApplyTemplate(); myAdornerLayer = AdornerLayer.GetAdornerLayer(this);
myAdornerLabel = new AdornerLabel(this, this.Label, this.LabelStyle);
UpdateAdorner(this); DependencyPropertyDescriptor focusProp = DependencyPropertyDescriptor.FromProperty(FrameworkElement.IsFocusedProperty, typeof(FrameworkElement));
if (focusProp != null)
{
focusProp.AddValueChanged(this, delegate
{
UpdateAdorner(this);
});
} DependencyPropertyDescriptor containsTextProp = DependencyPropertyDescriptor.FromProperty(ShadowedTextBox.HasTextProperty, typeof(ShadowedTextBox));
if (containsTextProp != null)
{
containsTextProp.AddValueChanged(this, delegate
{
UpdateAdorner(this);
});
}
} protected override void OnTextChanged(TextChangedEventArgs e)
{
HasText = this.Text != ""; base.OnTextChanged(e);
} protected override void OnDragEnter(DragEventArgs e)
{
myAdornerLayer.RemoveAdorners<AdornerLabel>(this); // requires AdornerExtensions.cs base.OnDragEnter(e);
} protected override void OnDragLeave(DragEventArgs e)
{
UpdateAdorner(this); base.OnDragLeave(e);
} private void UpdateAdorner(FrameworkElement elem)
{
if (((ShadowedTextBox)elem).HasText || elem.IsFocused)
{
// Hide the Shadowed Label
this.ToolTip = this.Label;
myAdornerLayer.RemoveAdorners<AdornerLabel>(elem); // requires AdornerExtensions.cs
}
else
{
// Show the Shadowed Label
this.ToolTip = null;
if (!myAdornerLayer.Contains<AdornerLabel>(elem)) // requires AdornerExtensions.cs
myAdornerLayer.Add(myAdornerLabel);
}
}
}
}