using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace FWindSoft.Wpf.Controls
{
///
/// 按照步骤 1a 或 1b 操作,然后执行步骤 2 以在 XAML 文件中使用此自定义控件。
///
/// 步骤 1a) 在当前项目中存在的 XAML 文件中使用该自定义控件。
/// 将此 XmlNamespace 特性添加到要使用该特性的标记文件的根
/// 元素中:
///
/// xmlns:MyNamespace="clr-namespace:WpfControl"
///
///
/// 步骤 1b) 在其他项目中存在的 XAML 文件中使用该自定义控件。
/// 将此 XmlNamespace 特性添加到要使用该特性的标记文件的根
/// 元素中:
///
/// xmlns:MyNamespace="clr-namespace:WpfControl;assembly=WpfControl"
///
/// 您还需要添加一个从 XAML 文件所在的项目到此项目的项目引用,
/// 并重新生成以避免编译错误:
///
/// 在解决方案资源管理器中右击目标项目,然后依次单击
/// “添加引用”->“项目”->[浏览查找并选择此项目]
///
///
/// 步骤 2)
/// 继续操作并在 XAML 文件中使用控件。
///
///
///
///
public class TextBoxEditor : Control, IEditableObject
{
public static readonly DependencyProperty IsEditingProperty= DependencyProperty.Register("IsEditing", typeof(bool), typeof(TextBoxEditor), new PropertyMetadata(false, null));
public static readonly DependencyProperty TextProperty = DependencyProperty.Register("Text", typeof(string), typeof(TextBoxEditor), new PropertyMetadata(null, null));
public static readonly DependencyProperty CommandProperty = DependencyProperty.Register("Command", typeof(ICommand), typeof(TextBoxEditor), new FrameworkPropertyMetadata(null));
public static readonly DependencyProperty CommandParameterProperty = DependencyProperty.Register("CommandParameter", typeof(object), typeof(TextBoxEditor), new FrameworkPropertyMetadata(null));
static TextBoxEditor()
{//new PropertyChangedCallback(PropertyChangedCallback)
DefaultStyleKeyProperty.OverrideMetadata(typeof(TextBoxEditor), new FrameworkPropertyMetadata(typeof(TextBoxEditor)));
}
public TextBoxEditor()
{
//this.IsReadOnly = true;
this.GotFocus += TextBoxEditor_GotFocus;
this.LostFocus += TextBoxEditor_LostFocus;
m_GetFocus = false;
}
private bool m_GetFocus;
private void TextBoxEditor_GotFocus(object sender, RoutedEventArgs e)
{
if (this.Equals(sender))
{
m_GetFocus = true;
}
}
private void TextBoxEditor_LostFocus(object sender, RoutedEventArgs e)
{
if (this.Equals(sender))
{
var dis = this.Dispatcher; // System.Windows.Threading.Dispatcher.CurrentDispatcher;
//这个多线程有点用了
dis.BeginInvoke(System.Windows.Threading.DispatcherPriority.Input,
new Action(() =>
{
//Thread.Sleep(1000);
if (m_GetFocus)
{
m_GetFocus = false;
}
else
{
CancelEdit();
IsEditing = false;
}
}));
}
}
protected override void OnLostFocus(RoutedEventArgs e)
{
//base.OnLostFocus(e);
//CancelEdit();
//IsEditing = false;
}
///
/// 关联textBox
///
public TextBox TextBox { get; private set; }
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
var btnUpdate = this.Template.FindName("BtnUpdate",this) as Button;
if (btnUpdate != null)
{
btnUpdate.Click += BtnUpdate_Click;
}
var btnClear = this.Template.FindName("BtnClear", this) as Button;
if (btnClear != null)
{
btnClear.Click += BtnClear_Click; ;
}
var btnComplete = this.Template.FindName("BtnComplete", this) as Button;
if (btnComplete != null)
{
btnComplete.Click += BtnComplete_Click; ;
}
var textBox = this.Template.FindName("PART_ContentHost", this) as TextBox;
if (textBox != null)
{
TextBox = textBox;
}
}
private void BtnComplete_Click(object sender, RoutedEventArgs e)
{
EndEdit();
IsEditing = false;
}
private void BtnClear_Click(object sender, RoutedEventArgs e)
{
CancelEdit();
IsEditing = false;
}
private void BtnUpdate_Click(object sender, RoutedEventArgs e)
{
if (!IsEditing)
{
IsEditing = !IsEditing;
BeginEdit();
}
}
#region IEditableObject 接口实现
private string TempText { get; set; }
public void BeginEdit()
{
TempText = this.Text;
TextBox.Focus();
if (this.Text != null)
{
TextBox.Select(this.Text.Count(), 0);
}
else
{
TextBox.Select(0, 0);
}
}
public void EndEdit()
{
//只在开始编辑时设置
//TempText = this.Text;
}
public void CancelEdit()
{
this.Text = TempText;
}
#endregion
public bool IsEditing
{
get { return (bool) this.GetValue(IsEditingProperty); }
set { this.SetValue(IsEditingProperty, value); }
}
public string Text
{
get { return this.GetValue(TextProperty) as string; }
set { this.SetValue(TextProperty, value); }
}
public ICommand Command
{
get
{
return (ICommand)base.GetValue(CommandProperty);
}
set
{
base.SetValue(CommandProperty, value);
}
}
public object CommandParameter
{
get
{
return base.GetValue(CommandParameterProperty);
}
set
{
base.SetValue(CommandParameterProperty, value);
}
}
}
}