Intercept Silverlight DatePicker's convert from text to DateTime
I want DatePicker
to convert the following text pieces to DateTime
(shown in international format) so my customers can write a date in DatePicker
textbox faster so it is not just DateTime.Parse
I will use:
"3" to 2009-10-03
"14" to 2009-10-14
"1403" to 2009-03-14
"140310" to 2010-03-14
"14032010" to 2010-03-14
I have tried different methods to do it but they do not work. I have tried to bind DatePicker.Text
/DatePicker.SelectedDate
/DatePicker.DisplayDate
with a custom valueconverter. But it do not work because DatePicker
already have processed the text before I get to the text.
I have also tried to convert in the DatePicker
TextBox.LostFocus
like this:
public class CustomDatePicker : DatePicker
{
private DatePickerTextBox textBox;
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
textBox = this.GetTemplateChild("TextBox") as DatePickerTextBox;
if (textBox != null)
textBox.LostFocus += textBox_开发者_如何学运维LostFocus;
}
void textBox_LostFocus(object sender, RoutedEventArgs e)
{
if (textBox == null) return;
DateTime result;
// This is my method for converting my special cases,
// parses d, dd, mm, ddmm, ddmmyy, ddmmyyyy
if (textBox.Text.TryParseShortcut(out result))
{
// I have also tried with
// this.SelectedDate/DisplayDate = result;
textBox.Text = result.ToString("dd/MM/yyyy");
return;
}
if (DateTime.TryParse(textBox.Text, out result))
{
// I have also tried with
// this.SelectedDate/DisplayDate = result;
textBox.Text = result.ToString("dd/MM/yyyy");
return;
}
}
}
Any ideas?
If you use Binding to bind data to your DatePicker, you could use a ValueConverter.
Quick example of date converter:
public class CustomDateValueConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value is string)
{
string dateValue = (string)value;
switch (dateValue.Length)
{
case 1:
case 2:
return new DateTime(DateTime.Now.Year, DateTime.Now.Month, System.Convert.ToInt32(dateValue)).ToString("dd/MM/yyyy");
//...
}
}
return value;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
// here you should implement your logic to convert your value back.
return value;
}
}
DatePickerTextBox control in XAML:
<controls:DatePickerTextBox Text="{Binding Path=Data, Mode=TwoWay, Converter={StaticResource CustomDateValueConverter}}" />
DatePickerTextBox in cs:
public partial class MainPage : UserControl
{
public MainPage()
{
InitializeComponent();
DataContext = new MyData() { Data = "3" };
_textBox.LostFocus += (se, ea) =>
{
_textBox.DataContext =
new MyData() { Data = _textBox.Text };
};
}
public class MyData
{
public string Data { get; set; }
}
I have just made a class called MyData to use as data in this sample.
I think you might need to actually start will the full control source and customize that. The problem is that the text gets updated in the TextChanged event:
private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
{
if (this._textBox != null)
{
this.SetValueNoCallback(TextProperty, this._textBox.Text);
}
}
So by the time you get to your lost focus code, the value has already been set. I was able to get around this using subclassing, but since TextChanged handles every change I'm not sure your parse method will work (Since as soon as you hit 1 number it will get changed to a date).
public class CustomDatePicker : DatePicker
{
private TextBox textBox;
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
textBox = this.GetTemplateChild("TextBox") as TextBox;
if (textBox != null)
textBox.TextChanged += textBox_TextChanged;
}
void textBox_TextChanged(object sender, TextChangedEventArgs e)
{
if (textBox.Text == "now")
{
// I have also tried with
// this.SelectedDate/DisplayDate = result;
textBox.Text = DateTime.Now.ToShortDateString();
}
}
}
It works for me since nothing changes until it spells the whole word, but in your case that probably won't work.
精彩评论