.NET MAUI自定义DateTimePicker控件:InitializeComponent()对象引用错误求助
问题原因分析
你遇到的InitializeComponent()错误,核心原因是自定义控件的代码放错了位置:
InitializeComponent()方法是由XAML文件自动生成的,每个XAML对应的代码-behind类(比如MainPage.xaml对应MainPage.xaml.cs)只能调用自己的InitializeComponent()。- 你把
MyPicker这个自定义ContentView的代码放到了MainPage.xaml.cs中,导致MyPicker类调用的InitializeComponent()找不到对应的MyPicker.xaml生成的代码,同时代码中引用的entry、pickerLayout控件也不存在于MainPage的XAML布局中,因此抛出对象引用缺失的错误。
解决步骤
1. 创建自定义控件的独立文件
在MAUI项目中添加专属的自定义ContentView:
- 右键项目 → 「添加」→ 「新项」→ 选择「.NET MAUI ContentView」,命名为
MyPicker,这会自动生成MyPicker.xaml和MyPicker.xaml.cs两个文件。 - 将你提供的
MyPicker类代码,替换MyPicker.xaml.cs中的默认代码。
2. 完善MyPicker的XAML布局
打开MyPicker.xaml,添加entry和pickerLayout控件(确保控件名称和代码中引用的一致),示例布局如下:
<?xml version="1.0" encoding="utf-8" ?> <ContentView xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="YourAppNamespace.MyPicker"> <VerticalStackLayout> <!-- 用于显示选择结果的Entry --> <Entry x:Name="entry" Text="{Binding SelectedDateTimeString}" Focused="OnEntryFocused"/> <!-- 日期选择器布局,默认隐藏 --> <VerticalStackLayout x:Name="pickerLayout" IsVisible="False"> <DateTimePicker x:Name="dateTimePicker" Date="{Binding SelectedDateTime}"/> <Button Text="确认" Clicked="OnPickerOKClicked"/> </VerticalStackLayout> </VerticalStackLayout> </ContentView>
注意替换YourAppNamespace为你项目的实际命名空间。
3. 修正代码中的问题
移除阻塞UI的轮询逻辑
删除WaitForChangedResult()方法,以及OnEntryFocused中的await Task.Run(() => WaitForChangedResult());——这种轮询会阻塞线程,完全没必要,点击「确认」按钮时已经处理了布局显示切换。
修正属性通知逻辑
确保你的MyVM实现INotifyPropertyChanged接口(MVVM模式的核心要求),示例VM代码:
using System.ComponentModel; using System.Runtime.CompilerServices; namespace YourAppNamespace { public class MyVM : INotifyPropertyChanged { private DateTime _selectedDateTime = DateTime.Now; public DateTime SelectedDateTime { get => _selectedDateTime; set { _selectedDateTime = value; OnPropertyChanged(); // 自动同步格式化后的字符串 SelectedDateTimeString = value.ToString("yyyy-MM-dd HH:mm"); } } private string _selectedDateTimeString; public string SelectedDateTimeString { get => _selectedDateTimeString; set { _selectedDateTimeString = value; OnPropertyChanged(); } } public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged([CallerMemberName] string propertyName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } } }
然后修改OnPickerOKClicked方法,直接更新VM的选中值即可:
private void OnPickerOKClicked(object sender, EventArgs e) { pickerLayout.IsVisible = false; entry.IsVisible = true; // 更新VM中的选中日期,自动同步到Entry显示 vm.SelectedDateTime = dateTimePicker.Date; }
4. 在MainPage中使用自定义控件
打开MainPage.xaml,引入自定义控件的命名空间,然后添加MyPicker:
<?xml version="1.0" encoding="utf-8" ?> <ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:local="clr-namespace:YourAppNamespace" x:Class="YourAppNamespace.MainPage"> <VerticalStackLayout Padding="20"> <local:MyPicker/> </VerticalStackLayout> </ContentPage>
内容的提问来源于stack exchange,提问作者JimRamey
相关产品推荐
相关产品推荐

