UWP C#如何在不同页面上使用例程

问题描述

我打算用navigationview编写一个UWP,在其中我使用rs485与某些设备进行通信。

我有一个DS3231 RTC,我之前已经在较早的应用程序中使它正常工作。

我的SettingPage是我配置时间的地方,当我设置时间时,我遇到了错误system.nullreferenceexception: 'object reference not set to an instance of an object.'

我的startClock()readDS3231setDS3231例程位于MainPage.xaml.cs中。 我的datepickertimepicker例程位于SettingsPage中。

请帮助让我知道我在哪里做错了以及如何纠正它。 实际上,我对page很困惑。我不明白。


SettingsPage.xaml.cs

private void DatePicker_DateChanged(object sender,DatePickerValueChangedEventArgs e)
    {
        DateTimeSettings.SetSystemDateTime(e.NewDate.UtcDateTime);

        mainPage.SetTime_DS3231(e.NewDate.UtcDateTime);
    }

private void TimePicker_TimeChanged(object sender,TimePickerValueChangedEventArgs e)
    {
        var currentDate = DateTime.Now.ToUniversalTime();

        var newDateTime = new DateTime(currentDate.Year,currentDate.Month,currentDate.Day,e.NewTime.Hours,e.NewTime.Minutes,e.NewTime.Seconds);

        DateTimeSettings.SetSystemDateTime(newDateTime);

        mainPage.SetTime_DS3231(newDateTime);
    }

private void TimeZoneComboBox_SelectionChanged(object sender,SelectionChangedEventArgs e)
    {
        TimeZoneInfo selectedTimeZone = (TimeZoneInfo)this.TimeZoneComboBox.SelectedItem;
        Zone.Text = selectedTimeZone.ToString();
        TimeZoneInfo.ConvertTime(DateTime.Now,selectedTimeZone);
    }

private void UpdateRTC_Click(object sender,RoutedEventArgs e)
    {
        mainPage.SetTime_DS3231(DateTime.Now);
    }

private void ReadRTC_Click(object sender,RoutedEventArgs e)
    {
        mainPage.GetTime_DS3231();

        ReadSec.Text = mainPage.readSec;
        ReadMin.Text = mainPage.readMin;
        ReadHour.Text = mainPage.readHour;
        ReadDay.Text = mainPage.readDay;
        ReadDate.Text = mainPage.readDate;
        ReadMth.Text = mainPage.readMth;
        ReadYear.Text = mainPage.readYear;
    }

MainPage.xaml.cs

public async void GetTime_DS3231()
    {
        /* DS3231 I2C SLAVE address */
        int SlaveAddress = 0x68;

        try
        {
            // Initialize I2C
            var Settings = new I2cConnectionSettings(SlaveAddress);
            Settings.Busspeed = I2cBusspeed.StandardMode;

            if (AQS == null || dis == null)
            {
                AQS = I2cDevice.GetDeviceSelector("I2C1");
                dis = await Deviceinformation.FindAllAsync(AQS);
            }

            //rtcError = false;

            using (I2cDevice Device = await I2cDevice.FromIdAsync(dis[0].Id,Settings))
            {
                byte[] writeBuf = { 0x00 };
                Device.Write(writeBuf);
                byte[] readBuf = new byte[7];
                Device.Read(readBuf);
                byte second = bcdToDec((byte)(readBuf[0] & 0x7f));
                byte minute = bcdToDec(readBuf[1]);
                byte hour = bcdToDec((byte)(readBuf[2] & 0x3f));
                byte dayOfWeek = bcdToDec(readBuf[3]);
                byte dayOfMonth = bcdToDec(readBuf[4]);
                byte month = bcdToDec(readBuf[5]);
                byte year = bcdToDec(readBuf[6]);

                readSec = second.ToString();
                readMin = minute.ToString();
                readHour = hour.ToString();
                readDay = dayOfWeek.ToString();
                readDate = dayOfMonth.ToString();
                readMth = month.ToString();
                readYear = year.ToString();
                
                var currentDate = DateTime.Now.ToUniversalTime();

                var newDateTime = new DateTime(currentDate.Year,month,dayOfMonth,hour,minute,second);

                DateTimeSettings.SetSystemDateTime(newDateTime);

            }
        }
        catch (Exception ex)
        {
            MainStatusdisplay.Text = ex.Message;
            //System.Diagnostics.Debug.Write(ex.Message);
        }
    }

    public async void SetTime_DS3231(DateTime dt)
    {
        int SlaveAddress = 0x68;

        try
        {
            // Initialize I2C
            var Settings = new I2cConnectionSettings(SlaveAddress);
            Settings.Busspeed = I2cBusspeed.StandardMode;

            if (AQS == null || dis == null)
            {
                AQS = I2cDevice.GetDeviceSelector("I2C1");
                dis = await Windows.Devices.Enumeration.Deviceinformation.FindAllAsync(AQS);
            }

            //rtcError = false;

            using (I2cDevice Device = await I2cDevice.FromIdAsync(dis[0].Id,Settings))
            {
                byte write_seconds = decToBcd((byte)dt.Second);
                byte write_minutes = decToBcd((byte)dt.Minute);
                byte write_hours = decToBcd((byte)dt.Hour);
                byte write_dayofweek = decToBcd((byte)dt.DayOfWeek);
                byte write_day = decToBcd((byte)dt.Day);
                byte write_month = decToBcd((byte)dt.Month);
                //byte write_year = decToBcd((byte)dt.Year);
                byte write_year = IntToBcd(dt.Year % 100);

                byte[] write_time = { 0x00,write_seconds,write_minutes,write_hours,write_dayofweek,write_day,write_month,write_year };

                Device.Write(write_time);

            }
        }
        catch (Exception ex)
        {
            //rtcError = true;
            MainStatusdisplay.Text = ex.Message;
            //System.Diagnostics.Debug.Write(ex.Message);
        }

    }

enter image description here

enter image description here

enter image description here

enter image description here

解决方法

必须使用SettingsPage.mainPage当前活动的页面实例初始化成员MainPage。如果不使用MVVM,事情将变得复杂而丑陋。因此,我建议引入一个在两个视图之间共享的视图模型。

还请注意,异步方法必须返回Task,否则您将遇到奇怪的行为,尤其是当等待方法引发异常时。您还忘记了await异步方法。考虑遵循最佳做法的命名约定,并将“ Async”后缀添加到异步方法,例如GetTime_DS3231Async

MainViewModel.cs

class MainViewModel : INotifyPropertyChanged
{
    public async Task GetTimeDs3231Async()
    {
        /* DS3231 I2C SLAVE address */
        int SlaveAddress = 0x68;

        try
        {
            // Initialize I2C
            var Settings = new I2cConnectionSettings(SlaveAddress);
            Settings.BusSpeed = I2cBusSpeed.StandardMode;

            if (AQS == null || DIS == null)
            {
                AQS = I2cDevice.GetDeviceSelector("I2C1");
                DIS = await DeviceInformation.FindAllAsync(AQS);
            }

            //rtcError = false;

            using (I2cDevice Device = await I2cDevice.FromIdAsync(DIS[0].Id,Settings))
            {
                byte[] writeBuf = { 0x00 };
                Device.Write(writeBuf);
                byte[] readBuf = new byte[7];
                Device.Read(readBuf);
                byte second = bcdToDec((byte)(readBuf[0] & 0x7f));
                byte minute = bcdToDec(readBuf[1]);
                byte hour = bcdToDec((byte)(readBuf[2] & 0x3f));
                byte dayOfWeek = bcdToDec(readBuf[3]);
                byte dayOfMonth = bcdToDec(readBuf[4]);
                byte month = bcdToDec(readBuf[5]);
                byte year = bcdToDec(readBuf[6]);

                readSec = second.ToString();
                readMin = minute.ToString();
                readHour = hour.ToString();
                readDay = dayOfWeek.ToString();
                readDate = dayOfMonth.ToString();
                readMth = month.ToString();
                readYear = year.ToString();
                
                var currentDate = DateTime.Now.ToUniversalTime();

                var newDateTime = new DateTime(currentDate.Year,month,dayOfMonth,hour,minute,second);

                DateTimeSettings.SetSystemDateTime(newDateTime);

            }
        }
        catch (Exception ex)
        {
            MainStatusDisplay.Text = ex.Message;
            //System.Diagnostics.Debug.Write(ex.Message);
        }
    }

    public async Task SetTimeDs3231Async(DateTime dt)
    {
        int SlaveAddress = 0x68;

        try
        {
            // Initialize I2C
            var Settings = new I2cConnectionSettings(SlaveAddress);
            Settings.BusSpeed = I2cBusSpeed.StandardMode;

            if (AQS == null || DIS == null)
            {
                AQS = I2cDevice.GetDeviceSelector("I2C1");
                DIS = await Windows.Devices.Enumeration.DeviceInformation.FindAllAsync(AQS);
            }

            //rtcError = false;

            using (I2cDevice Device = await I2cDevice.FromIdAsync(DIS[0].Id,Settings))
            {
                byte write_seconds = decToBcd((byte)dt.Second);
                byte write_minutes = decToBcd((byte)dt.Minute);
                byte write_hours = decToBcd((byte)dt.Hour);
                byte write_dayofweek = decToBcd((byte)dt.DayOfWeek);
                byte write_day = decToBcd((byte)dt.Day);
                byte write_month = decToBcd((byte)dt.Month);
                //byte write_year = decToBcd((byte)dt.Year);
                byte write_year = IntToBcd(dt.Year % 100);

                byte[] write_time = { 0x00,write_seconds,write_minutes,write_hours,write_dayofweek,write_day,write_month,write_year };

                Device.Write(write_time);

            }
        }
        catch (Exception ex)
        {
            //rtcError = true;
            MainStatusDisplay.Text = ex.Message;
            //System.Diagnostics.Debug.Write(ex.Message);
        }    
    }
}

App.xaml

<Application>
  <Application.Resources>
    <MainViewModel x:Key="MainViewModel"/>
  </Application.Resources>
</Application>

MainPage.xam

<Page DataContext="{StaticResource MainViewModel}">

</Page>

SettingsPage.xam

<Page DataContext="{StaticResource MainViewModel}">

</Page>

SettingsPage.xaml.cs

private async void DatePicker_DateChanged(object sender,DatePickerValueChangedEventArgs e)
{
    DateTimeSettings.SetSystemDateTime(e.NewDate.UtcDateTime);

    var viewModel = this.DataContext as MainViewModel;

    // Await the asynchronous method
    await viewModel.SetTimeDs3231Async(e.NewDate.UtcDateTime);
}
,

在您使用mainPage.SetTime_DS3231(newDateTime)时,变量mainPage的值为null。确保已正确初始化。 在此之前它已经初始化了吗?然后可能会在代码执行过程中的某个时候将其删除,例如在切换页面时。

您可以尝试将其放在mainPage.SetTime_DS3231(newDateTime)之前:

if(mainPage == null)
    mainPage = new MainPage();

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...