using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
namespace GeekDesk.EditTextBlock
{
public class EditableTextBlock : TextBlock
{
public bool IsInEditMode
{
get
{
return (bool)GetValue(IsInEditModeProperty);
}
set
{
SetValue(IsInEditModeProperty, value);
}
}
private EditableTextBlockAdorner _adorner;
// Using a DependencyProperty as the backing store for IsInEditMode. This enables animation, styling, binding, etc...
public static readonly DependencyProperty IsInEditModeProperty =
DependencyProperty.Register("IsInEditMode", typeof(bool), typeof(EditableTextBlock), new UIPropertyMetadata(false, IsInEditModeUpdate));
///
/// Determines whether [is in edit mode update] [the specified obj].
///
/// The obj.
/// The instance containing the event data.
private static void IsInEditModeUpdate(DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
EditableTextBlock textBlock = obj as EditableTextBlock;
if (null != textBlock)
{
//Get the adorner layer of the uielement (here TextBlock)
AdornerLayer layer = AdornerLayer.GetAdornerLayer(textBlock);
//If the IsInEditMode set to true means the user has enabled the edit mode then
//add the adorner to the adorner layer of the TextBlock.
if (textBlock.IsInEditMode)
{
if (null == textBlock._adorner)
{
textBlock._adorner = new EditableTextBlockAdorner(textBlock);
//Events wired to exit edit mode when the user presses Enter key or leaves the control.
textBlock._adorner.TextBoxKeyUp += textBlock.TextBoxKeyUp;
textBlock._adorner.TextBoxLostFocus += textBlock.TextBoxLostFocus;
}
layer.Add(textBlock._adorner);
}
else
{
//Remove the adorner from the adorner layer.
Adorner[] adorners = layer.GetAdorners(textBlock);
if (adorners != null)
{
foreach (Adorner adorner in adorners)
{
if (adorner is EditableTextBlockAdorner)
{
layer.Remove(adorner);
}
}
}
//Update the textblock's text binding.
BindingExpression expression = textBlock.GetBindingExpression(TextProperty);
if (null != expression)
{
expression.UpdateTarget();
}
}
}
}
///
/// Gets or sets the length of the max.
///
/// The length of the max.
public int MaxLength
{
get
{
return (int)GetValue(MaxLengthProperty);
}
set
{
SetValue(MaxLengthProperty, value);
}
}
// Using a DependencyProperty as the backing store for MaxLength. This enables animation, styling, binding, etc...
public static readonly DependencyProperty MaxLengthProperty =
DependencyProperty.Register("MaxLength", typeof(int), typeof(EditableTextBlock), new UIPropertyMetadata(0));
private void TextBoxLostFocus(object sender, RoutedEventArgs e)
{
IsInEditMode = false;
}
///
/// release the edit mode when user presses enter.
///
/// The sender.
/// The instance containing the event data.
private void TextBoxKeyUp(object sender, KeyEventArgs e)
{
if (e.Key == Key.Enter)
{
IsInEditMode = false;
}
}
///
/// Invoked when an unhandled attached event reaches an element in its route that is derived from this class. Implement this method to add class handling for this event.
///
/// The that contains the event data. This event data reports details about the mouse button that was pressed and the handled state.
protected override void OnMouseDown(MouseButtonEventArgs e)
{
if (e.MiddleButton == MouseButtonState.Pressed)
{
IsInEditMode = true;
}
else if (e.ClickCount == 2)
{
IsInEditMode = true;
}
}
}
}