You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 19:43:21