拦截Silverlight DatePicker从文本转换为DateTime
-
05-07-2019 - |
题
我希望 DatePicker
将以下文本片段转换为 DateTime
(以国际格式显示),以便我的客户可以在 DatePicker
中写一个日期文本框更快,所以它不仅仅是 DateTime.Parse
我将使用:
"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
我尝试过不同的方法,但它们不起作用。我尝试使用自定义valueconverter绑定 DatePicker.Text
/ DatePicker.SelectedDate
/ DatePicker.DisplayDate
。但它不起作用,因为 DatePicker
在我到达文本之前已经处理了文本。
我还试图像这样转换 DatePicker
TextBox.LostFocus
:
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;
}
}
}
有什么想法吗?
解决方案
如果使用Binding将数据绑定到DatePicker,则可以使用ValueConverter。
日期转换器的快速示例:
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;
}
}
XAML中的DatePickerTextBox控件:
<controls:DatePickerTextBox Text="{Binding Path=Data, Mode=TwoWay, Converter={StaticResource CustomDateValueConverter}}" />
cs中的DatePickerTextBox:
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; }
}
我刚刚创建了一个名为MyData的类,用作此示例中的数据。
其他提示
我认为你可能需要真正启动完整的控制源并自定义它。问题是文本在TextChanged事件中更新:
private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
{
if (this._textBox != null)
{
this.SetValueNoCallback(TextProperty, this._textBox.Text);
}
}
因此,当您找到丢失的焦点代码时,该值已经设置。我能够使用子类来解决这个问题,但是由于TextChanged处理每个更改,我不确定你的解析方法是否有效(因为只要你点击1个数字就会改变为日期)。
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();
}
}
}
它适用于我,因为它没有任何变化,直到它拼写整个单词,但在你的情况下可能不起作用。
不隶属于 StackOverflow