代码之家  ›  专栏  ›  技术社区  ›  Lasse Espeholt

截获Silverlight DatePicker从文本到日期时间的转换

  •  2
  • Lasse Espeholt  · 技术社区  · 16 年前

    我想要 DatePicker 将以下文本段转换为 DateTime (以国际格式显示)这样我的客户就可以用 日期选择器 文本框速度更快,因此它不仅仅是 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
    

    我尝试过不同的方法,但都不管用。我试着把它绑起来 DatePicker.Text / DatePicker.SelectedDate / DatePicker.DisplayDate 使用自定义值转换器。但它不起作用,因为 在我进入文本之前已经处理了文本。

    我也曾尝试在 日期选择器 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; 
            }
        }
    }
    

    有什么想法吗?

    2 回复  |  直到 14 年前
        1
  •  1
  •   thomasmartinsen    16 年前

    如果使用绑定将数据绑定到日期选择器,则可以使用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}}" />
    

    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; }
    }
    

        2
  •  0
  •   casperOne    14 年前

    我认为您可能需要实际启动will完整的控制源代码并对其进行自定义。问题是文本在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();                 
            }  
        }
    }
    

    它对我来说很有用,因为在拼写出整个单词之前,不会有任何变化,但在你的情况下,这可能不起作用。

    推荐文章