簡體   English   中英

UWP C# 如何使用來自不同頁面的例程

[英]UWP C# How to Use Routine From Different Page

我打算用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的事情很困惑。 我無法理解。


設置頁面.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);
        }

    }

在此處輸入圖像描述

在此處輸入圖像描述 在此處輸入圖像描述 在此處輸入圖像描述

您必須使用MainPage的當前活動頁面實例初始化成員SettingsPage.mainPage 如果你不使用 MVVM,事情就會變得復雜和丑陋。 出於這個原因,我建議引入一個在兩個視圖之間共享的視圖 model。

另請注意,異步方法必須返回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);
        }    
    }
}

申請.xaml

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

主頁.xam

<Page DataContext="{StaticResource MainViewModel}">

</Page>

設置頁面.xam

<Page DataContext="{StaticResource MainViewModel}">

</Page>

設置頁面.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();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM