xamarin 表单中的 datepicker 和 timepicker 多次触发 Focus 和 Unfocus 事件

Posted

技术标签:

【中文标题】xamarin 表单中的 datepicker 和 timepicker 多次触发 Focus 和 Unfocus 事件【英文标题】:Focus and Unfocus events are triggering multiple times for datepicker and timepicker in xamarin forms 【发布时间】:2021-09-27 20:19:13 【问题描述】:

我在我的应用程序中使用了日期选择器和时间选择器。

我为日期选择器和时间选择器实现了焦点和非焦点事件。 使用 focus 和 unfocus 事件验证最大日期的时间。

那些焦点和非焦点事件会触发多次。 当我们点击日期选择器或时间选择器时需要触发一次。

XAML:

<controls:DatePickerCustom x:Name="DatePicker" FontSize="14" HeightRequest="35" Date="Binding CustomDate,Mode=TwoWay" MaximumDate="Binding MaximumDate" FontFamily="Segoe UI" Format="D"  HorizontalOptions="FillAndExpand" Unfocused="DatePickerUnfocused" TranslationX="-4">
                                    <DatePicker.Triggers>
                                        <DataTrigger TargetType="DatePicker" Binding="Binding IsCustomSelected" Value="true">
                                            <Setter Property="TextColor" Value="DynamicResource HeadingTextColor" />
                                            <Setter Property="TextColor" Value="DynamicResource HeadingTextColor" />
                                        </DataTrigger>
                                    </DatePicker.Triggers>
                                </controls:DatePickerCustom>


<controls:TimePickerCustom x:Name="TimePicker" FontSize="14" HeightRequest="35" Time="Binding CustomTime,Mode=TwoWay" FontFamily="Segoe UI" Focused="TimePickerFocused" Unfocused="TimePickerUnfocused" >
                                    <TimePicker.Triggers>
                                        <DataTrigger TargetType="TimePicker" Binding="Binding IsCustomSelected" Value="true">
                                            <Setter Property="TextColor" Value="DynamicResource HeadingTextColor" />
                                        </DataTrigger>
                                    </TimePicker.Triggers>
                                </controls:TimePickerCustom>

CS:

protected void TimePickerUnfocused(object sender, FocusEventArgs e)
        
            TimePicker picker = sender as TimePicker;
            if (DatePicker.Date.ToString("dd/MM/yyyy") == DatePicker.MaximumDate.ToString("dd/MM/yyyy"))
            
                //var t1 = Convert.ToDateTime(DateTime.Now).ToString("HH:mm");
                //var t2 = Convert.ToDateTime(picker.Time.ToString()).ToString("HH:mm");

                var result = DateTime.Compare(Convert.ToDateTime(Convert.ToDateTime(DateTime.Now).ToString("HH:mm")), Convert.ToDateTime(Convert.ToDateTime(picker.Time.ToString()).ToString("HH:mm")));

                if (result > 0)
                
                    if (endValue.ToString() != "00:00:00")
                    
                        TimePicker.Time = endValue;
                    
                    else
                    
                        endValue = picker.Time;
                        TimePicker.Time = endValue;
                    
                
                else
                
                    DisplayAlert("Alert!", "Please select the valid time", "OK");
                    TimePicker.Time = TimeSpan.Parse(DateTime.Now.AddHours(-1).ToString("HH:mm"));
                
            

        

        protected void DatePickerUnfocused(object sender, FocusEventArgs e)
        
            if (DatePicker.Date.ToString("dd/MM/yyyy HH:mm") == DatePicker.MaximumDate.ToString("dd/MM/yyyy HH:mm"))
            
                if(endValue.ToString() != "00:00:00")
                
                    TimePicker.Time = endValue;
                
                else if (startValue.ToString() != "00:00:00")
                
                    TimePicker.Time = startValue;
                
                else
                
                    startValue= TimeSpan.Parse(DateTime.Now.AddHours(-1).ToString("HH:mm"));
                    TimePicker.Time = startValue;
                
            
        

        protected void TimePickerFocused(object sender, FocusEventArgs e)
        
            if (DatePicker.Date.ToString("dd/MM/yyyy HH:mm") == DatePicker.MaximumDate.ToString("dd/MM/yyyy HH:mm") && startValue != null)
            
                TimePicker.Time = startValue;
            
        

并且日期选择器的MinimumDate和MaximumDate属性在android 10版本的真机上不起作用。相同的属性在模拟器中起作用。

【问题讨论】:

我无法重现您的问题,它只会在我身边触发一次焦点和取消焦点。也许您可以尝试使用 PropertyChanged 方法来监听选择时间事件。 【参考方案1】:

可能的解决方法:

根据特定选择器是否获得焦点设置一个布尔值。忽略任何重复的焦点消息。

日期选择器示例:

private bool _datePickerFocused = false;

protected void DatePickerFocused(...)

    // Skip if already focused.
    if (_datePickerFocused)
        return;

    _datePickerFocused = true;
    ...


protected void DatePickerUnfocused(...)

    // Skip if not focused.
    if (!_datePickerFocused)
        return;

    _datePickerFocused = false;
    ...

【讨论】:

以上是关于xamarin 表单中的 datepicker 和 timepicker 多次触发 Focus 和 Unfocus 事件的主要内容,如果未能解决你的问题,请参考以下文章

Xamarin.Forms DatePicker 时间

如何在 xamarin 表单中更改视觉材料 DatePickerDialog 和 TimePickerDialog 背景颜色

Xamarin Forms 渲染器未响应事件更改

如何在 Xamarin 中为 DatePicker 添加最小日期验证检查

更改 DatePicker [Xamarin.Forms] 的颜色

带农历日历的DatePicker控件!Xamarin控件开发小记