.NET Maui中DatePicker与TimePicker的Focused事件不触发
问题:.NET Maui中DatePicker/TimePicker的Focused事件不触发
将Xamarin项目迁移至.NET Maui后,表单内的Entry、Editor、Picker控件的Focused/Unfocused事件可正常触发,实现当前聚焦控件的高亮效果,但DatePicker和TimePicker点击时不会触发Focused事件,导致高亮停留在之前的控件上,该逻辑在原Xamarin应用中可正常工作。
相关代码
XAML代码
<Grid Padding="10,0,10,0" ColumnDefinitions="150,200" RowDefinitions="40"> <Label Margin="15,0,0,0" Style="{StaticResource LabelEntry}" Text="End Date" /> <DatePicker x:Name="endDatePicker" Grid.Row="0" Grid.Column="1" BackgroundColor="Transparent" Date="{Binding BeginDate}" DateSelected="endDatePicker_DateSelected" Focused="DatePickerHighlight" HorizontalOptions="Start" Unfocused="DatePickerHighlight" VerticalOptions="Center" /> </Grid> <Grid Padding="10,0,10,0" ColumnDefinitions="150,200" RowDefinitions="40"> <Label Margin="15,0,0,0" Style="{StaticResource LabelEntry}" Text="End Time" /> <TimePicker x:Name="endTimePicker" Grid.Row="0" Grid.Column="1" BackgroundColor="Transparent" Focused="TimePickerHighlight" Format="HH:mm" HorizontalOptions="Start" Time="{Binding BeginDate}" Unfocused="TimePickerHighlight" VerticalOptions="Center" /> </Grid>
后台代码
private void DatePickerHighlight(object sender, FocusEventArgs e) { var myentry = sender as DatePicker; var myGrid = myentry.Parent as Grid; if (e.IsFocused) { myGrid.BackgroundColor = App.HighlightColor; } else myGrid.BackgroundColor = Color.White; } private void TimePickerHighlight(object sender, FocusEventArgs e) { var myentry = sender as TimePicker; var myGrid = myentry.Parent as Grid; if (e.IsFocused) { myGrid.BackgroundColor = App.HighlightColor; } else myGrid.BackgroundColor = Color.White; }
原因与解决方案
原因
这并非引用遗漏或代码错误,而是.NET Maui与Xamarin.Forms的控件实现逻辑差异:
- Xamarin.Forms中,点击DatePicker/TimePicker会先触发控件的Focused事件,再唤起系统选择器;
- .NET Maui中,这两个控件点击时直接唤起系统选择器,不会触发自身的Focused事件,仅通过代码调用
Focus()方法时才会触发该事件。
解决方案
方案1:使用Clicked事件替代Focused事件(推荐)
利用DatePicker/TimePicker的Clicked事件模拟聚焦效果,配合DateSelected/TimeSelected事件处理失焦逻辑,同时添加页面空白处点击事件处理用户取消选择的场景:
- 修改XAML,添加Clicked事件:
<DatePicker x:Name="endDatePicker" Grid.Row="0" Grid.Column="1" BackgroundColor="Transparent" Date="{Binding BeginDate}" DateSelected="endDatePicker_DateSelected" Clicked="DatePicker_Clicked" HorizontalOptions="Start" VerticalOptions="Center" /> <TimePicker x:Name="endTimePicker" Grid.Row="0" Grid.Column="1" BackgroundColor="Transparent" Clicked="TimePicker_Clicked" Format="HH:mm" HorizontalOptions="Start" Time="{Binding BeginDate}" TimeSelected="endTimePicker_TimeSelected" VerticalOptions="Center" />
- 修改后台代码:
private void DatePicker_Clicked(object sender, EventArgs e) { var picker = sender as DatePicker; var myGrid = picker.Parent as Grid; myGrid.BackgroundColor = App.HighlightColor; } private void endDatePicker_DateSelected(object sender, DateChangedEventArgs e) { var picker = sender as DatePicker; var myGrid = picker.Parent as Grid; myGrid.BackgroundColor = Color.White; // 保留原有的DateSelected业务逻辑 } private void TimePicker_Clicked(object sender, EventArgs e) { var picker = sender as TimePicker; var myGrid = picker.Parent as Grid; myGrid.BackgroundColor = App.HighlightColor; } private void endTimePicker_TimeSelected(object sender, TimeChangedEventArgs e) { var picker = sender as TimePicker; var myGrid = picker.Parent as Grid; myGrid.BackgroundColor = Color.White; // 保留原有的TimeSelected业务逻辑 } // 处理页面空白处点击,重置所有Grid背景色 private void Page_Tapped(object sender, TappedEventArgs e) { foreach (var child in (this.Content as Layout).Children) { if (child is Grid grid) { grid.BackgroundColor = Color.White; } } }
记得给页面添加Tapped事件:Tapped="Page_Tapped"
方案2:自定义控件强制触发Focus事件
如果希望保留原有的Focused/Unfocused事件逻辑,可自定义DatePicker/TimePicker,在点击时手动调用Focus():
- 创建自定义控件:
public class CustomDatePicker : DatePicker { protected override void OnClicked() { Focus(); base.OnClicked(); } } public class CustomTimePicker : TimePicker { protected override void OnClicked() { Focus(); base.OnClicked(); } }
- 在XAML中引用自定义控件(需添加命名空间):
xmlns:local="clr-namespace:你的项目命名空间" <local:CustomDatePicker x:Name="endDatePicker" Grid.Row="0" Grid.Column="1" BackgroundColor="Transparent" Date="{Binding BeginDate}" DateSelected="endDatePicker_DateSelected" Focused="DatePickerHighlight" Unfocused="DatePickerHighlight" HorizontalOptions="Start" VerticalOptions="Center" /> <local:CustomTimePicker x:Name="endTimePicker" Grid.Row="0" Grid.Column="1" BackgroundColor="Transparent" Focused="TimePickerHighlight" Format="HH:mm" HorizontalOptions="Start" Time="{Binding BeginDate}" Unfocused="TimePickerHighlight" VerticalOptions="Center" />
内容的提问来源于stack exchange,提问作者Gary H
相关产品推荐
相关产品推荐

