[英]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()
、 readDS3231
和setDS3231
例程位於MainPage.xaml.cs
。 我的datepicker
和timepicker
選擇器例程在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.