首页 > 解决方案 > Xamarin:Android / iOS 的不同行为(静态类?)

问题描述

我正在接管 Xamarin 上的一个项目。它适用于android,我希望它适用于iOS。

最初,它已经完成了,所以我希望它可能只适用于设置?

无论如何,它适用于Android,但不适用于iOS。

我有这个代码:

public App()
        {
            Debug.WriteLine(Current.Properties); //return default value
            try
            {
                ViewModelLocator.MainViewModel.RestoreState(Current.Properties);
                BindingContext = ViewModelLocator.MainViewModel;
                MainTabPage = new SGC400Tab();

                MainPage = MainTabPage;
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex);
            }
        }

public static class ViewModelLocator
        {
            private static GlobalViewModel _myViewModel = new GlobalViewModel();
            public static GlobalViewModel MainViewModel
            {
                get
                {
                    return _myViewModel;
                }
            }

        }

public class GlobalViewModel : INotifyPropertyChanged
    {    
    public void RestoreState(IDictionary<string, object> dictionary)
        {
            Thing1.SelectedUnitySystem_Presure = GetDictionaryEntry(dictionary, "SavedUnitySystem_Pression", "Bars");
            Thing1.SelectedUnitySystem_Flow = GetDictionaryEntry(dictionary, "SavedUnitySystem_Debit", "m3/h");
            Thing1.SelectedUnitySystem_Temperature = GetDictionaryEntry(dictionary, "SavedUnitySystem_Temperature", "°C");

            Thing1.SelectedLanguageKey = GetDictionaryEntry(dictionary, "SavedLanguage", "en");

        }
}

返回错误:

System.NullReferenceException 上线:

private static GlobalViewModel _myViewModel = new GlobalViewModel();

我对它在android上工作的事实有点困惑......但在iOS上却不行......

我不得不说我对 Xamarin 很陌生,你能给我一些指导吗?

先感谢您 !

PS:类 GlobalViewModel 在这里:

public class GlobalViewModel : INotifyPropertyChanged
{

    public event PropertyChangedEventHandler PropertyChanged;

    //#####################################
    //Enneigeur
    public Enneigeur _Enneigeur1 = new Enneigeur();
    public Enneigeur Enneigeur1
    {
        get { return _Enneigeur1; }
        set
        {
            _Enneigeur1 = value;
        }
    }
    //Com
    public ComSGC400 _comSGC400 = new ComSGC400();
    public ComSGC400 ComSGC400
    {
        get { return _comSGC400; }
        set { _comSGC400 = value; }
    }

    public const int TIMOUT_COM_MS = 500;
    public const int DELAI_ENTRE_TRAME_MS = 1000;
    //#####################################
    //Bluetooth

    public ObservableCollection<string> ListOfDevices { get; set; } = new ObservableCollection<string>();

    public string inputBuffer;
    public string SelectedBthDevice { get;set; } = "";

    private bool _isConnected { get; set; } = false;
    public bool IsConnected {
        get { return _isConnected; }
        set
        {
            _isConnected = value;
            if (_isConnected == true)
            {
                ((App)Application.Current).AddPages();
            } else
            {
                ((App)Application.Current).RemovePages();
            }
        }
    } 

    private bool _isSelectedBthDevice { get { if (string.IsNullOrEmpty(SelectedBthDevice)) return false; return true; }}
    public bool IsConnectEnabled { get { if (_isSelectedBthDevice == false) return false; return !IsConnected; }}
    public bool IsDisconnectEnabled { get { if (_isSelectedBthDevice == false) return false; return IsConnected; } }

    public Color ConnectBackgroundcolor { get { if (IsConnectEnabled) return Color.Green; return Color.FromRgb(48, 48, 48); } }
    public Color DisconnectBackgroundColor { get { if (IsDisconnectEnabled) return Color.Red; return Color.FromRgb(48, 48, 48); } }

    public bool IsConnectionInit { get { if (EtatGrafcet_loop < 2 || IsConnected == false ) return false; return true; } }
    public bool IsModeManuOK { get { if (EtatGrafcet_loop >= 2 && IsConnected == true && _Enneigeur1.Manu == true) return true; return false; } }
    public bool IsBoutonRotaOK { get { if (EtatGrafcet_loop >= 2 && IsConnected == true && ( _Enneigeur1._VersionSGC400 > 10213 || _Enneigeur1.Manu == true)) return true; return false; } }
    public bool IsPickerEnabled { get { return !IsConnected; }}

    public bool IsBalayageDispo { get { if (EtatGrafcet_loop < 2 || IsConnected == false || _Enneigeur1.OptionBalayageDispo == false) return false; return true; } }


    public LocalizedResources Resources { get; private set;}
    public Color Mode_Manu_Button_Text_Color
    {
        get
        {
            if (EtatGrafcet_loop < 2)
                return Color.Gray;
            else
                return Color.White;
        }
    }
    public Color Mode_Manu_Button_Color {
        get {
            if (EtatGrafcet_loop < 2)
                return Color.FromRgb(48, 48, 48);
            else
            {
                if (_Enneigeur1.ModeMarche == 1) return Color.Green; return Color.Black;
            }
        }
    }
    public Color Mode_Stop_Button_Text_Color
    {
        get
        {
            if (EtatGrafcet_loop < 2)
                return Color.Gray;
            else
                return Color.White;
        }
    }
    public Color Mode_Stop_Button_Color {
        get
        {
            if (EtatGrafcet_loop < 2)
                return Color.FromRgb(48, 48, 48);
            else
            {
                if (_Enneigeur1.ModeMarche == 2) return Color.Green; return Color.Black;
            }
        }
    }
    public Color Mode_Forcage_Button_Text_Color
    {
        get
        {
            if (EtatGrafcet_loop < 2)
                return Color.Gray;
            else
                return Color.White;
        }
    }
    public Color Mode_Forcage_Button_Color
    {
        get
        {
            if (EtatGrafcet_loop < 2)
                return Color.FromRgb(48, 48, 48);
            else
            {
                if (_Enneigeur1.ModeMarche == 0) return Color.Green; return Color.Black;
            }
        }
    }
    private CancellationTokenSource _ct { get; set; }
    private int EtatGrafcet_loop { get; set; }

    private DateTime timer_send = DateTime.Now;

    private bool envoiContinu = false;
    private string envoiWrite = "";

    private async Task Loop()
    {
        string bufferEnvoi = "";
        bool res;
        int erreur_cryptage = 0;
        EtatGrafcet_loop = 0;
        int reponseLen = 0;

        _Enneigeur1.ResetValues();

        _ct = new CancellationTokenSource();
        ComSGC400.AddrSGC400 = Convert.ToUInt16(SelectedBthDevice.Substring(5));

        while (_ct.IsCancellationRequested == false)
        {
            switch (EtatGrafcet_loop)
            {
                case 0://Envoi trame clé crypté
                    if (DateTime.Now > timer_send.AddMilliseconds(DELAI_ENTRE_TRAME_MS)) //Temps entre trames
                    { 
                        //Test d'echange de clé de cryptage
                        inputBuffer = "";
                        reponseLen = ComSGC400.Create_Trame_getKey(ref bufferEnvoi);
                        if (bufferEnvoi.Length > 0)
                        {
                            Xamarin.Forms.MessagingCenter.Send<App, string>((App)Xamarin.Forms.Application.Current, "WriteDatas", bufferEnvoi);
                            timer_send = DateTime.Now;
                            EtatGrafcet_loop = 1;
                        }
                    }
                    break;
                case 1: //attente reception clé crypté

                    if (DateTime.Now > timer_send.AddMilliseconds(TIMOUT_COM_MS)){ EtatGrafcet_loop = 0; break; } //timeout

                    if (inputBuffer != null)
                    {
                        ComSGC400.Trame_RechercheDebutTrame(ref inputBuffer);
                        if (inputBuffer.Length >= reponseLen)
                        {
                            inputBuffer = inputBuffer.Substring(0, reponseLen);
                            res = ComSGC400.Update_ProtectionKey( inputBuffer);
                            if (res == true)
                            {
                                //cle cryptage OK
                                bufferEnvoi = "";
                                EtatGrafcet_loop = 2;
                                erreur_cryptage = 0;
                            }
                            else
                            {
                                //cle cryptage non ok
                                bufferEnvoi = "";
                                EtatGrafcet_loop = 0;
                            }
                            inputBuffer = "";
                        }
                    }
                    break;
                case 2: //envoi trame readMain
                    if (envoiWrite != "")
                        EtatGrafcet_loop = 10;  //envoi write
                    else
                    { 
                         if (DateTime.Now > timer_send.AddMilliseconds(DELAI_ENTRE_TRAME_MS)) //Temps entre trames
                        {

                            reponseLen = ComSGC400.Create_Trame_ReadMain(ref bufferEnvoi);
                            if (bufferEnvoi.Length > 0)
                            {
                                inputBuffer = "";
                                Xamarin.Forms.MessagingCenter.Send<App, string>((App)Xamarin.Forms.Application.Current, "WriteDatas", bufferEnvoi);
                                timer_send = DateTime.Now;
                                EtatGrafcet_loop = 3;
                            }
                        }
                    }
                    break;
                case 3: //attente reponse trame readMain

                    if (DateTime.Now > timer_send.AddMilliseconds(TIMOUT_COM_MS)) {
                        EtatGrafcet_loop = 20; break;
                    } //timeout

                    if (inputBuffer != null)
                    {
                        ComSGC400.Trame_RechercheDebutTrame(ref inputBuffer);
                        if (inputBuffer.Length >= reponseLen)
                        {
                            inputBuffer = inputBuffer.Substring(0, reponseLen);
                            res = ComSGC400.Update_Enneigeur( inputBuffer, ref _Enneigeur1);
                            if (res == true)
                            {
                                //Message OK
                                bufferEnvoi = "";
                                EtatGrafcet_loop = 4;//Passage readCom
                                erreur_cryptage = 0;
                                _Enneigeur1.LastRead = DateTime.Now;
                            }
                            else
                            {
                                //Message NON OK
                                EtatGrafcet_loop = 20;
                            }
                            inputBuffer = "";
                        }
                    }
                    break;
                case 4: //envoi trame readCom
                    if (envoiWrite != "")
                        EtatGrafcet_loop = 10; //envoi write
                    else
                    {
                        if (DateTime.Now > timer_send.AddMilliseconds(50)) //Temps entre trames
                        {

                            reponseLen = ComSGC400.Create_Trame_ReadCom(ref bufferEnvoi);
                            if (bufferEnvoi.Length > 0)
                            {
                                inputBuffer = "";
                                Xamarin.Forms.MessagingCenter.Send<App, string>((App)Xamarin.Forms.Application.Current, "WriteDatas", bufferEnvoi);
                                timer_send = DateTime.Now;
                                EtatGrafcet_loop = 5;
                            }
                        }
                    }
                    break;
                case 5: //attente reponse trame readCom

                    if (DateTime.Now > timer_send.AddMilliseconds(TIMOUT_COM_MS)) {
                        EtatGrafcet_loop = 21; break;
                    } //timeout

                    if (inputBuffer != null)
                    {
                        ComSGC400.Trame_RechercheDebutTrame(ref inputBuffer);
                        if (inputBuffer.Length >= reponseLen)
                        {
                            inputBuffer = inputBuffer.Substring(0, reponseLen);
                            res = ComSGC400.Update_Enneigeur( inputBuffer, ref _Enneigeur1);
                            if (res == true)
                            {
                                //Message OK
                                bufferEnvoi = "";
                                EtatGrafcet_loop = 2; //Retour read main
                                erreur_cryptage = 0;
                                _Enneigeur1.LastRead = DateTime.Now;
                                if (_Enneigeur1.Reset)
                                    Send_value_bluetooth("reset", false);
                            }
                            else
                            {
                                //Message NON OK
                                EtatGrafcet_loop = 21;
                            }
                            inputBuffer = "";
                        }
                    }
                    break;
                case 10: //envoi  trame Write
                    inputBuffer = "";
                    Xamarin.Forms.MessagingCenter.Send<App, string>((App)Xamarin.Forms.Application.Current, "WriteDatas", envoiWrite);
                    timer_send = DateTime.Now;
                    EtatGrafcet_loop =11;
                    break;
                case 11: //attente reponse trame Write

                    if (DateTime.Now > timer_send.AddMilliseconds(TIMOUT_COM_MS)) { EtatGrafcet_loop = 20; break; } //timeout

                    if (inputBuffer != null)
                    {
                        ComSGC400.Trame_RechercheDebutTrame(ref inputBuffer);
                        if (inputBuffer.Length >= 16)
                        {
                            bufferEnvoi = "";
                            if (envoiContinu)
                            {
                                EtatGrafcet_loop = 10; //envoi continu
                            }
                            else
                            {
                                envoiWrite = "";
                                EtatGrafcet_loop = 2; //Retour read main
                            }
                            erreur_cryptage = 0;
                            _Enneigeur1.LastWrite = DateTime.Now;
                            inputBuffer = "";
                        }
                    }
                    break;

                case 20://Erreur de reception trame readMain
                    bufferEnvoi = "";
                    erreur_cryptage = erreur_cryptage + 1;
                    envoiWrite = "";
                    if (erreur_cryptage > 3)
                    {
                        _Enneigeur1.ResetValues();
                        erreur_cryptage = 0;
                        EtatGrafcet_loop = 0;
                    }
                    else
                    {
                        EtatGrafcet_loop = 2;
                    }

                    break;
                case 21://Erreur de reception trame readCom
                    bufferEnvoi = "";
                    erreur_cryptage = erreur_cryptage + 1;
                    envoiWrite = "";
                    if (erreur_cryptage > 3)
                    {
                        _Enneigeur1.ResetValues();
                        erreur_cryptage = 0;
                        EtatGrafcet_loop = 0;
                    }
                    else
                    {
                        EtatGrafcet_loop = 4;
                    }

                    break;
                default:
                    EtatGrafcet_loop = 0;
                    break;
            }

            await Task.Delay(10);
        }
        EtatGrafcet_loop = 0;
    }

    public void Send_value_bluetooth(string nom_param, bool value)
    {
        if (value == true) Send_value_bluetooth( nom_param, 1); else Send_value_bluetooth(nom_param, 0);
    }
    public void Send_value_bluetooth(string nom_param, double value)
    {
        //la modif de Enneigeur1 entraine l'envoi d'une trame WRITE en bluetooth (si la liaison est OK)
        string bufferEnvoi = "";
        if (EtatGrafcet_loop >= 2)
        {
            switch(nom_param.ToLower())
            {
                Cases...
            }
        }
    }
    public void ExitApp()
    {
        // Disconnect from bth device
        DependencyService.Get<IBtInterface>().Disconnect();
        MessagingCenter.Unsubscribe<App, string>(this, "ReadDatas");
        IsConnected = false;

        if (_ct != null)
        {
            System.Diagnostics.Debug.WriteLine("Send a cancel to task!");
            _ct.Cancel();
        }
    }
    public GlobalViewModel()
    {
        Resources = new LocalizedResources(typeof(AppResources), Enneigeur1._SelectedLanguageKey
            );

        MessagingCenter.Subscribe<App>(this, "Sleep", (obj) =>
        {
            // When the app "sleep", I close the connection with bluetooth
            if (IsConnected)
                DependencyService.Get<IBtInterface>().Disconnect();
        });

        MessagingCenter.Subscribe<App>(this, "Resume", (obj) =>
        {
            // When the app "resume" I try to restart the connection with bluetooth
            if (IsConnected)
                DependencyService.Get<IBtInterface>().Connect(SelectedBthDevice);
        });

        this.InitCommand = new Command(() =>
        {
            // Try to connect to a bth device
            DependencyService.Get<IBtInterface>().Init();
        });

        this.ConnectCommand = new Command(() =>
        {
            EtatGrafcet_loop = 0;
            // Try to connect to a bth device
            IsConnected = DependencyService.Get<IBtInterface>().Connect(SelectedBthDevice);

            //second essai
            if (IsConnected == false) IsConnected = DependencyService.Get<IBtInterface>().Connect(SelectedBthDevice);

            if (IsConnected == true)
            {
                // initialisation des echange de données 
                MessagingCenter.Subscribe<App, string>(this, "ReadDatas", (sender, arg) =>
                {
                    //inputBuffer = inputBuffer + arg;
                    inputBuffer = inputBuffer + arg;
                });

                Task.Run(async () => Loop());
            }else
            {
                //erreur aux 2 tentatives de connection 
                //Task.Run(async () => ((App)Application.Current).OpenTextBoxDialog());
                ((App)Application.Current).OpenTextBoxDialog();
            }

        });

        this.DisconnectCommand = new Command(() =>
        {
            EtatGrafcet_loop = 0;
            ExitApp();
        });

        this.RefreshListDeviceCommand = new Command(() =>
        {
            try
            {
                ListOfDevices = DependencyService.Get<IBtInterface>().PairedDevices();
            }
            catch (Exception ex)
            {
                Application.Current.MainPage.DisplayAlert("Attention", ex.Message, "Ok");
            }
        });

        // At startup, I load all paired devices
        try
        {
            ListOfDevices = DependencyService.Get<IBtInterface>().PairedDevices();
        }
        catch (Exception ex)
        {
            Application.Current.MainPage.DisplayAlert("Attention", ex.Message, "Ok");
        }
    }

    private object Await(App current)
    {
        throw new NotImplementedException();
    }

    public ICommand InitCommand { get; protected set; }
    public ICommand ConnectCommand { get; protected set; }
    public ICommand DisconnectCommand { get; protected set; }
    public ICommand RefreshListDeviceCommand { get; protected set; }

    public void SaveState(IDictionary<string, object> dictionary)
    {
        dictionary["SavedLanguage"] = Enneigeur1._SelectedLanguageKey;

        dictionary["SavedUnitySystem_Pression"] = Enneigeur1.SelectedUnitySystem_Presure;
        dictionary["SavedUnitySystem_Debit"] = Enneigeur1.SelectedUnitySystem_Flow;
        dictionary["SavedUnitySystem_Temperature"] = Enneigeur1.SelectedUnitySystem_Temperature;
    }

    public void RestoreState(IDictionary<string, object> dictionary)
    {
        Enneigeur1.SelectedUnitySystem_Presure = GetDictionaryEntry(dictionary, "SavedUnitySystem_Pression", "Bars");
        Enneigeur1.SelectedUnitySystem_Flow = GetDictionaryEntry(dictionary, "SavedUnitySystem_Debit", "m3/h");
        Enneigeur1.SelectedUnitySystem_Temperature = GetDictionaryEntry(dictionary, "SavedUnitySystem_Temperature", "°C");

        Enneigeur1.SelectedLanguageKey = GetDictionaryEntry(dictionary, "SavedLanguage", "en");

    }

    public T GetDictionaryEntry<T>(IDictionary<string, object> dictionary,
                                    string key, T defaultValue)
    {
        if (dictionary.ContainsKey(key))
            return (T)dictionary[key];

        return defaultValue;
    }
}

标签: c#xamarin.formsxamarin.androidxamarin.ios

解决方案


推荐阅读