注意如果设置了系统dateformat格式。在变化系统culture的时候需要设置dateformat
CultureInfo info = new CultureInfo(this.LanguageItems[value].Name); info.DateTimeFormat.ShortDatePattern= "dd/MM/yyyy"; info.DateTimeFormat.LongDatePattern = "dd/MM/yyyy"; Thread.CurrentThread.CurrentCulture = info; Thread.CurrentThread.CurrentUICulture = info;
在textbox中设置
InputMethod.IsInputMethodEnabled=“false”;可以禁止textbox禁用IME开关,(做到不允许中文字符的输入)
// 若要将光标置于 TextBox 控件的内容的开头,应调用 Select 方法,并指定选择内容的起始位置为 0,选择长度为 0。
//1 textBox1.Select(0, 0); //若要将光标置于 TextBox 控件的内容的末尾,应调用 Select 方法,并指定选择内容的起始位置等于文本内容的长度,选择长度为 0。 //1 textBox1.Select(textBox1.Text.Length, 0); //若要将光标置于 TextBox 控件的内容的当前位置,应调用 Select 方法,并指定选择内容的起始位置等于光标的当前位置,选择长度为 0。 //1 textBox1.Select(textBox1.SelectionStart, 0); //原因是通过鼠标让TextBox获得输入焦点时,TextBox触发的事件顺序是:MouseDown->GotFocus->MouseUp, // 也就是说TextBox在鼠标按下的那一刻已经获得了输入焦点,此时可以对Select(0, 0)设置焦点位置。 // 但郁闷的是,MouseUp却会取消TextBox状态...也就是说文本焦点其实曾经被设置了,但立即又被取消(-_-#)textbox 用鼠标获得焦点的顺序是 mouseDown GotFocus mouseUP. mouseup会把gotFocus设置的select取消
View Code
private void MyTextBox_GotFocus(object sender, RoutedEventArgs e) { this.MyTextBox.Tag = true; if (this.SelectedDate != null) { this.MyTextBox.Text = string.Format("{0:dd/MM/yyyy}", this.SelectedDate.GetValueOrDefault()); } else { UpdateInputMask(); // this.MyTextBox.Text = "__/__/____"; this.MyTextBox.Select(0, 0); } }
所有在mouseup的时候要设置
View Code
private void MyTextBox_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e) { if (this.SelectedDate==null) { if (e.ChangedButton == MouseButton.Left && (bool)this.MyTextBox.Tag == true) { this.MyTextBox.Select(0, 0); } this.MyTextBox.Tag = false; } }
使用tag来标记。。是否是左击鼠标获得焦点。。获得之后就不在设置焦点位置
样式
:
View Code
#FFE8EDF9 #FFC5CBF9 #FF7381F9 #FFE8EDF9 #FFC5CBF9 #FF888888 #FFC5CBF9 #FFDDDDDD White #FF7381F9 #FF211AA9 #FF3843C4 #FF211AA9 #FF444444 sc#1, 0.004391443, 0.002428215, 0.242281124 #FFCCCCCC #FF888888 #FF444444 #FF888888 #FF444444 #FFAAAAAA #FF888888 Black #FFC5CBF9 Black #FFC5CBF9 #FF3843C4
cs.
View Code
using MCE.Gems.Common.Common;using MCE.Gems.Common.Events;using Microsoft.Practices.Prism.Events;using Microsoft.Practices.ServiceLocation;using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Windows;using System.Windows.Controls;using System.Windows.Input;namespace MCE.Gems.Common.Controls.CustomControls{ public class CustomDatePicker : DatePicker { #region Field // private static IEventAggregator eventAggregator = ServiceLocator.Current.GetInstance(); private List _maskChars; private static string currentWaterMark; private bool isTextChanged; private int _caretIndex; #endregion #region Property /// /// Gets the text box in charge of the editable portion of the MyDatePicker. /// protected TextBox MyTextBox { get { return base.GetTemplateChild("PART_MyTextBox") as TextBox; } } public string WaterMark { get { return (string)GetValue(WaterMarkProperty); } set { SetValue(WaterMarkProperty, value); } } // Using a DependencyProperty as the backing store for WaterMark. This enables animation, styling, binding, etc... public static readonly DependencyProperty WaterMarkProperty = DependencyProperty.Register("WaterMark", typeof(string), typeof(CustomDatePicker), new PropertyMetadata(null,new PropertyChangedCallback(OnWaterMarkChanged))); public DateTime DefaultCalendarDisplayDate { get { return (DateTime)GetValue(DefaultCalendarDisplayDateProperty); } set { SetValue(DefaultCalendarDisplayDateProperty, value); } } // Using a DependencyProperty as the backing store for DefaultCalendarDisplayDate. This enables animation, styling, binding, etc... public static readonly DependencyProperty DefaultCalendarDisplayDateProperty = DependencyProperty.Register("DefaultCalendarDisplayDate", typeof(DateTime), typeof(CustomDatePicker), new PropertyMetadata(null)); ////// Invoked when the WaterMark dependency property reports a change. /// /// /// private static void OnWaterMarkChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e) { CustomDatePicker cdp = obj as CustomDatePicker; if (cdp.SelectedDate==null&&cdp.MyTextBox!=null) { cdp.MyTextBox.Text = e.NewValue.ToString(); } currentWaterMark = e.NewValue.ToString(); } #endregion static CustomDatePicker() { DefaultStyleKeyProperty.OverrideMetadata(typeof(CustomDatePicker), new FrameworkPropertyMetadata(typeof(CustomDatePicker))); } public CustomDatePicker() { // eventAggregator.GetEvent().Subscribe(UpdateMaskLanguage); this._maskChars = new List (); } public override void OnApplyTemplate() { base.OnApplyTemplate(); //load the text box control if (this.MyTextBox != null) { this.MyTextBox.GotFocus += new RoutedEventHandler(MyTextBox_GotFocus); this.MyTextBox.LostFocus += new RoutedEventHandler(MyTextBox_LostFocus); this.MyTextBox.TextChanged += new TextChangedEventHandler(MyTextBox_TextChanged); this.MyTextBox.PreviewMouseLeftButtonUp += new MouseButtonEventHandler(MyTextBox_PreviewMouseLeftButtonUp); this.MyTextBox.PreviewKeyDown += MyTextBox_PreviewKeyDown; this.MyTextBox.PreviewTextInput += MyTextBox_PreviewTextInput; this.MyTextBox.SelectionChanged += MyTextBox_SelectionChanged; //default this.MyTextBox.Text = currentWaterMark; this.SelectedDateChanged += CustomDatePicker_SelectedDateChanged; this.Loaded += CustomDatePicker_Loaded; DataObject.AddPastingHandler(this, new DataObjectPastingEventHandler(MyTextBox_Paste)); //UpdateInputMask(); } } void CustomDatePicker_SelectedDateChanged(object sender, SelectionChangedEventArgs e) { //if (this.IsLoaded) //{ if (this.SelectedDate != null) { this.MyTextBox.Text = string.Format("{0:dd/MM/yyyy}", this.SelectedDate.GetValueOrDefault()); UpdateInputMask(); this._caretIndex = 10; this.MyTextBox.CaretIndex = 10; } else { this.MyTextBox.Text = WaterMark; } //} // this.DisplayDate = DateTime.Today; } void CustomDatePicker_Loaded(object sender, RoutedEventArgs e) { if (this.SelectedDate != null) { this.MyTextBox.Text = string.Format("{0:dd/MM/yyyy}", this.SelectedDate.GetValueOrDefault()); } else { // this.MyTextBox.Text = WaterMark; } } void MyTextBox_SelectionChanged(object sender, RoutedEventArgs e) { if (!isTextChanged) { TextBox t = (TextBox)sender; this._caretIndex = t.CaretIndex; } isTextChanged = false; } /// /// Invokes when a paste event is raised. /// /// /// private void MyTextBox_Paste(object sender, DataObjectPastingEventArgs e) { //TODO: play nicely here? // if (e.DataObject.GetDataPresent(typeof(string))) { string value = e.DataObject.GetData(typeof(string)).ToString(); string displayText; if (this.ValidateTextInternal(value, out displayText)) { this.MyTextBox.Text = displayText; } } e.CancelCommand(); } private void MyTextBox_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e) { if (this.SelectedDate == null) { if (e.ChangedButton == MouseButton.Left && (bool)this.MyTextBox.Tag == true) { this.MyTextBox.Select(0, 0); } this.MyTextBox.Tag = false; } } private void MyTextBox_TextChanged(object sender, TextChangedEventArgs e) { isTextChanged = true; if (string.IsNullOrWhiteSpace(this.MyTextBox.Text)) { this.SelectedDate = null; this.MyTextBox.Text = WaterMark; } } private void MyTextBox_LostFocus(object sender, RoutedEventArgs e) { if (this.MyTextBox.Text != null) { try { this.SelectedDate = DateTime.Parse(this.MyTextBox.Text); //this.DisplayDate = DateTime.Today; } catch (Exception) { this.SelectedDate = null; this.MyTextBox.Text = WaterMark; // this.MyTextBox.Text = null; } } if (this.DefaultCalendarDisplayDate != null) { this.DisplayDate = this.DefaultCalendarDisplayDate; } //if (this.SelectedDate != null) //{ // this.MyTextBox.Text = string.Format("{0:dd/MM/yyyy}", this.SelectedDate.GetValueOrDefault()); //} //else //{ // //this.MyTextBox.Text = WaterMark; //} } private void MyTextBox_GotFocus(object sender, RoutedEventArgs e) { this.MyTextBox.Tag = true; if (this.SelectedDate != null) { this.MyTextBox.Text = string.Format("{0:dd/MM/yyyy}", this.SelectedDate.GetValueOrDefault()); } else { UpdateInputMask(); // this.MyTextBox.Text = "__/__/____"; this.MyTextBox.Select(0, 0); } } void MyTextBox_PreviewKeyDown(object sender, KeyEventArgs e) { //no mask specified, just function as a normal textbox if (this._maskChars.Count == 0) return; if (e.Key == Key.Delete) { //delete key pressed: delete all text this.MyTextBox.Text = this.GetDefaultText(); this._caretIndex = this.MyTextBox.CaretIndex = 0; e.Handled = true; } else { //backspace key pressed if (e.Key == Key.Back) { if (this._caretIndex > 0 || this.MyTextBox.SelectionLength > 0) { if (this.MyTextBox.SelectionLength > 0) { //if one or more characters selected, delete them this.DeleteSelectedText(); } else { //if no characters selected, shift the caret back to the previous non-literal char and delete it this.MoveBack(); char[] characters = this.MyTextBox.Text.ToCharArray(); characters[this._caretIndex] = this._maskChars[this._caretIndex].GetDefaultChar(); this.MyTextBox.Text = new string(characters); } //update the base class caret index, and swallow the event this.MyTextBox.CaretIndex = this._caretIndex; e.Handled = true; } } else if (e.Key == Key.Left) { //move back to the previous non-literal character this.MoveBack(); e.Handled = true; } else if (e.Key == Key.Right || e.Key == Key.Space) { //move forwards to the next non-literal character this.MoveForward(); e.Handled = true; } } } void MyTextBox_PreviewTextInput(object sender, TextCompositionEventArgs e) { if (this._maskChars.Count == 0) return; this._caretIndex = this.MyTextBox.CaretIndex = this.MyTextBox.SelectionStart; if (this._caretIndex == this._maskChars.Count) { //at the end of the character count defined by the input mask- no more characters allowed e.Handled = true; } else { //validate the character against its validation scheme bool isValid = this.ValidateInputChar(char.Parse(e.Text), this._maskChars[this._caretIndex].ValidationFlags); if (isValid) { //delete any selected text if (this.MyTextBox.SelectionLength > 0) { this.DeleteSelectedText(); } //insert the new character char[] characters = this.MyTextBox.Text.ToCharArray(); characters[this._caretIndex] = char.Parse(e.Text); this.MyTextBox.Text = new string(characters); //move the caret on this.MoveForward(); } e.Handled = true; } } #region validateMethod protected virtual bool IsPlaceholderChar(char character, out InputMaskValidationFlags validationFlags) { validationFlags = InputMaskValidationFlags.None; switch (character.ToString().ToUpper()) { case "I": validationFlags = InputMaskValidationFlags.AllowInteger; break; case "D": validationFlags = InputMaskValidationFlags.AllowDecimal; break; case "A": validationFlags = InputMaskValidationFlags.AllowAlphabet; break; case "W": validationFlags = (InputMaskValidationFlags.AllowAlphanumeric); break; } return (validationFlags != InputMaskValidationFlags.None); } ////// Returns a value indicating if the current text value is valid. /// ///public virtual bool ValidateTextInternal(string text, out string displayText) { if (this._maskChars.Count == 0) { displayText = text; return true; } StringBuilder displayTextBuilder = new StringBuilder(this.GetDefaultText()); bool valid = (!string.IsNullOrEmpty(text) && text.Length <= this._maskChars.Count); if (valid) { for (int i = 0; i < text.Length; i++) { if (!this._maskChars[i].IsLiteral()) { if (this.ValidateInputChar(text[i], this._maskChars[i].ValidationFlags)) { displayTextBuilder[i] = text[i]; } else { valid = false; } } } } displayText = displayTextBuilder.ToString(); return valid; } /// /// Validates the specified character against all selected validation schemes. /// /// /// ///protected virtual bool ValidateInputChar(char input, InputMaskValidationFlags validationFlags) { bool valid = (validationFlags == InputMaskValidationFlags.None); if (!valid) { Array values = Enum.GetValues(typeof(InputMaskValidationFlags)); //iterate through the validation schemes foreach (object o in values) { InputMaskValidationFlags instance = (InputMaskValidationFlags)(int)o; if ((instance & validationFlags) != 0) { if (this.ValidateCharInternal(input, instance)) { valid = true; break; } } } } return valid; } /// /// Validates the specified character against its input mask validation scheme. /// /// /// ///private bool ValidateCharInternal(char input, InputMaskValidationFlags validationType) { bool valid = false; switch (validationType) { case InputMaskValidationFlags.AllowInteger: case InputMaskValidationFlags.AllowDecimal: int i; if (validationType == InputMaskValidationFlags.AllowDecimal && input == '.' && !this.MyTextBox.Text.Contains('.')) { valid = true; } else { valid = int.TryParse(input.ToString(), out i); } break; case InputMaskValidationFlags.AllowAlphabet: valid = char.IsLetter(input); break; case InputMaskValidationFlags.AllowAlphanumeric: valid = (char.IsLetter(input) || char.IsNumber(input)); break; } return valid; } #endregion #region Method public void UpdateInputMask() { string text = this.MyTextBox.Text; this._maskChars.Clear(); // this.MyTextBox.Text = string.Empty; string mask = "ii/ii/iiii"; //if (string.IsNullOrEmpty(mask)) // return; this._maskChars.Add(new InputMaskChar() { Literal = (char)0, DefaultChar = 'd', ValidationFlags = InputMaskValidationFlags.AllowInteger }); this._maskChars.Add(new InputMaskChar() { Literal = (char)0, DefaultChar = 'd', ValidationFlags = InputMaskValidationFlags.AllowInteger }); this._maskChars.Add(new InputMaskChar() { Literal = (char)1, DefaultChar = '/', ValidationFlags = InputMaskValidationFlags.None }); this._maskChars.Add(new InputMaskChar() { Literal = (char)0, DefaultChar = 'M', ValidationFlags = InputMaskValidationFlags.AllowInteger }); this._maskChars.Add(new InputMaskChar() { Literal = (char)0, DefaultChar = 'M', ValidationFlags = InputMaskValidationFlags.AllowInteger }); this._maskChars.Add(new InputMaskChar() { Literal = (char)1, DefaultChar = '/', ValidationFlags = InputMaskValidationFlags.None }); this._maskChars.Add(new InputMaskChar() { Literal = (char)0, DefaultChar = 'y', ValidationFlags = InputMaskValidationFlags.AllowInteger }); this._maskChars.Add(new InputMaskChar() { Literal = (char)0, DefaultChar = 'y', ValidationFlags = InputMaskValidationFlags.AllowInteger }); this._maskChars.Add(new InputMaskChar() { Literal = (char)0, DefaultChar = 'y', ValidationFlags = InputMaskValidationFlags.AllowInteger }); this._maskChars.Add(new InputMaskChar() { Literal = (char)0, DefaultChar = 'y', ValidationFlags = InputMaskValidationFlags.AllowInteger }); //InputMaskValidationFlags validationFlags = InputMaskValidationFlags.None; //for (int i = 0; i < mask.Length; i++) //{ // bool isPlaceholder = this.IsPlaceholderChar(mask[i], out validationFlags); // if (isPlaceholder) // { // this._maskChars.Add(new InputMaskChar(validationFlags)); // } // else // { // this._maskChars.Add(new InputMaskChar(mask[i])); // } //} string displayText; if (text.Length > 0 && this.ValidateTextInternal(text, out displayText)) { this.MyTextBox.Text = displayText; } else { this.MyTextBox.Text = this.GetDefaultText(); } } private void UpdateMaskLanguage(string obj) { if (this.SelectedDate == null) { //this.MyTextBox.Text = WaterMark; } } public string GetDefaultText() { StringBuilder text = new StringBuilder(); foreach (InputMaskChar maskChar in this._maskChars) { text.Append(maskChar.GetDefaultChar()); } return text.ToString(); } /// /// Moves the caret forward to the next non-literal position. /// private void MoveForward() { int pos = this._caretIndex; while (pos < this._maskChars.Count) { if (++pos == this._maskChars.Count || !this._maskChars[pos].IsLiteral()) { this._caretIndex = this.MyTextBox.CaretIndex = pos; break; } } } ////// Moves the caret backward to the previous non-literal position. /// private void MoveBack() { int pos = this._caretIndex; while (pos > 0) { if (--pos == 0 || !this._maskChars[pos].IsLiteral()) { this._caretIndex = this.MyTextBox.CaretIndex = pos; break; } } } ////// Deletes the currently selected text. /// protected virtual void DeleteSelectedText() { StringBuilder text = new StringBuilder(this.MyTextBox.Text); string defaultText = this.GetDefaultText(); int selectionStart = this.MyTextBox.SelectionStart; int selectionLength = this.MyTextBox.SelectionLength; text.Remove(selectionStart, selectionLength); text.Insert(selectionStart, defaultText.Substring(selectionStart, selectionLength)); this.MyTextBox.Text = text.ToString(); //reset the caret position this.MyTextBox.CaretIndex = this._caretIndex = selectionStart; } #endregion [Flags] protected enum InputMaskValidationFlags { None = 0, AllowInteger = 1, AllowDecimal = 2, AllowAlphabet = 4, AllowAlphanumeric = 8 } private class InputMaskChar { private InputMaskValidationFlags _validationFlags; private char _literal; public char DefaultChar { get; set; } public InputMaskChar(InputMaskValidationFlags validationFlags) { this._validationFlags = validationFlags; this._literal = (char)0; } public InputMaskChar(char literal) { this._literal = literal; } public InputMaskChar() { } public InputMaskValidationFlags ValidationFlags { get { return this._validationFlags; } set { this._validationFlags = value; } } public char Literal { get { return this._literal; } set { this._literal = value; } } public bool IsLiteral() { return (this._literal != (char)0); } public char GetDefaultChar() { return DefaultChar; } } } }