输入文本时 DatePicker.SelectedDate 不变

Posted

技术标签:

【中文标题】输入文本时 DatePicker.SelectedDate 不变【英文标题】:DatePicker.SelectedDate not changing when Text is input 【发布时间】:2011-05-31 08:21:32 【问题描述】:

当我的用户通过 DatePicker 中的 Calander 控件选择日期时,该值会正确绑定到底层对象。但是,如果用户在 DatePicker 中键入日期,然后单击按钮,则文本不会设置为 SelectedDate 属性。

用户必须从 DatePicker 内的 TextBox 中移除光标才能更新绑定的对象。

 <toolkit:DatePicker Name="_dpField" Grid.Column="1" MinWidth="100"
               ToolTip="Binding Path=ToolTipText"
               TextInput="_dpField_TextInput"
               SelectedDate="Binding Path=Value, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay"/>

帮助!我如何确保在按钮事件代码中使用了这个类型的值?

谢谢!

【问题讨论】:

【参考方案1】:

我找到了一个不需要DateConverter 的更简单的解决方案。

我只绑定到Text 属性并使用TargetNullValue=''

<DatePicker x:Name = "dpDisbursementDate" 
            Text = "Binding NameOfMyProperty, Mode=TwoWay,    
            UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True, 
            TargetNullValue=''"/>

【讨论】:

这真是鬼鬼祟祟! 这真是太棒了!对我来说就像一个魅力。 这个答案似乎解决了原来的问题,但还有另一个危险的问题并没有立即显现出来:不同的日期格式没有正确解析。我来自芬兰,我们使用 dd.mm.yyyy 格式。此实现将当前日期 2014 年 12 月 9 日解析为 2014 年 9 月 11 日。 我试过这个,但我发现和 Ville Salonen 一样的问题。那么,有没有人找到另一种解决方案? 拯救了我的一天..... :) (我也看到了语言环境的影响,但在我的实际用例中我不必费心......)【参考方案2】:

您可以使用转换器将输入的文本解析为有效的日期时间

示例

 public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    
        string strValue = System.Convert.ToString(value);
        DateTime resultDateTime;
        if (DateTime.TryParse(strValue, out resultDateTime))
        
            return resultDateTime;
        
        return value;

    

Xaml

     <Controls:DatePicker 
     Text="Binding OrderDate,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged"
     SelectedDate="Binding RelativeSource=RelativeSource Self,Path=Text,
     Converter=StaticResource DateConverter">

【讨论】:

知道了,我能做到。我只是好奇为什么只有当我故意模糊日期选择器的文本框时才会发生所选日期的绑定。我想我需要问另一个关于 WPF 的单击事件的问题,以及为什么它不会导致绑定在为按钮单击触发事件之前将值推送到绑定对象。感谢您的帮助 Update 刚刚实现了转换器,并且可以正常工作。现在开始一个关于绑定模式和点击事件的新问题。 我使用了该方法,但它不起作用,因为如果我在 UI 上输入文本,它需要 ConvertBack 方法。 当 DatePicker 值为空时,我总是在值“”上得到 ValidationErrors。唯一真正有效的解决方案是绑定DateTime?属性为 Text 并设置 TargetNullValue='',就像下面来自 @Slampen 的答案【参考方案3】:

我能找到的唯一解决方案是通过设置Focusable="False" 来禁止在 DatePicker 中输入日期,并且只允许从日历中进行选择。这样我们至少可以确保我们得到正确的日期。

【讨论】:

【参考方案4】:

这是一个简单的解决方案,即使使用欧洲/德国日期格式“dd.MM.yyyy”也能帮助我。

添加到您的 xaml 根元素

xml:lang="de-AT"

日期选择器看起来像这样:

<DatePicker SelectedDate="Binding PropertyName, StringFormat=dd.MM.yyyy" Name="datePicker" />

希望它对你有用!

【讨论】:

这对我们有用,但我们需要将 StringFormat 放在 Text 上,而不是 SelectedDate。我使用了比 'dd.MM.yyyy' 更标准的 \d: 【参考方案5】:

在我的特殊情况下,我有一个 Button,它在从文本更新日期之前在其 ViewModel 中启动了一个操作。但是,将下面的函数绑定到按钮 Click(Click 和 Action 都已绑定)会在操作开始之前覆盖所需的日期。

private void UpdateDateBeforeAction(object sender, RoutedEventArgs e)

    bool parseSuccess = DateTime.TryParse(this.myDatePicker.Text, out DateTime parsedDate);
    if (parseSuccess && this.DataContext is MyParticularViewModel vm)
    
        vm.targetDate = parsedDate;
    

编辑:实际上你甚至不需要触摸视图模型

if(parseSuccess)

    this.myDatePicker.SelectedDate = parsedDate;

【讨论】:

【参考方案6】:

这可能有点晚了,但我已经坚持了一段时间了。

如果您有另一个 WPF 元素,您可以在按钮按下事件开始时将焦点更改为该元素,这将使日期选择器处理在其文本框中输入的任何文本。我只用组合框试过这个,但它似乎工作,它允许你仍然有你的日期自定义格式(即 26/04/2016 而不是 04/26/2016)。如果你没有任何东西可以改变焦点,我假设你也可以使用不可见的元素。

    private void btnInbound_Complete_Click(object sender, RoutedEventArgs e)
    
        if (Validation())
        
            comboInbound_Result.Focus();//THIS IS SO THAT ANY MANUAL DATEPICKER ENTRY IS ACCEPTED BEFORE THE REST OF THE BUTTON CODE IS RUN
            SQLinbound_CompleteItem();
            ClearAll();
        
    

【讨论】:

以上是关于输入文本时 DatePicker.SelectedDate 不变的主要内容,如果未能解决你的问题,请参考以下文章

输入长文本时如何调整文本视图的大小?

输入文本时自动扩展的 Flutter 文本字段,然后在达到特定高度时开始滚动文本

将文本输入到另一个输入字段时清除输入字段

空白时自定义文本输入更改标签

分配文本输入固定字体大小时,如何使文本输入和按钮具有相同的高度?

在输入时验证 html 文本输入