2017-07-06 2 views
1

ich eine Tabbed-Seite wie diese bin mit:Gibt es Leistungs- oder Codierungsprobleme beim Übergeben eines Objekts an mehrere Seiten, um Variablen für Registerkartenseiten freizugeben?

public partial class MainPage : TabbedPage 
{ 

    public MainPage() 
    { 
     InitializeComponent(); 

     var phrasesPage = new NavigationPage(new PhrasesPage()) 
     { 
      Title = "Play", 
      Icon = "play.png" 
     }; 
     .... 
     Children.Add(phrasesPage); 
     Children.Add(categoriesPage); 
     Children.Add(favoritesPage); 
     Children.Add(settingsPage); 
     Children.Add(aboutPage); 
    } 

Ich möchte Variablen zwischen meinen Seiten teilen. Zum Beispiel eine Score-Nummer, die auf allen Seiten und einigen anderen Variablen angezeigt wird.

Ich möchte meine Anwendung so programmieren, dass sie einfach zu pflegen ist.

public partial class MainPage : TabbedPage 
{ 

    public class Person 
    { 
     public string Name { get; set; } 
     public int Age { get; set; } 
     public Person(){} 
     public Person(string name, int age) 
     { 
      Name = name; 
      Age = age; 
     } 
    } 

    public MainPage() 
    { 
     InitializeComponent(); 

     var person = Person p=new Person() 
     { 
      Name = "Han Solo", 
      Age = 39 
     }; 

     var phrasesPage = new NavigationPage(new PhrasesPage(person)) 
     { 
      Title = "Play", 
      Icon = "play.png" 
     }; 
     .... 
     .... 
     Children.Add(phrasesPage); 
     Children.Add(categoriesPage); 
     Children.Add(favoritesPage); 
     Children.Add(settingsPage); 
     Children.Add(aboutPage); 
    } 

Kann mich jemand raten, wenn es gut sei, um ein Objekt zu erstellen, die all freigegebenen Variablen enthalten und dann das Objekt an den Konstruktor von jedem der Seiten als Parameter zu übergeben, wenn die Seiten mit einem erstellt werden "Neu"?

Antwort

2

Wir haben eine Klasse zum Speichern und Abrufen von Objekten in und aus einem statischen Wörterbuch von Objekten erstellt, sie befindet sich in unserer PCL, könnte aber in Formularen als generischer kompilierbarer Code verwendet werden.

Erstellen Sie die Klasse:

public static class ApplicationState 
{ 
    private static Dictionary<string, object> _values = 
       new Dictionary<string, object>(); 

    /// <summary> 
    /// Sets a value in the dictionary with the entered values. 
    /// </summary> 
    /// <param name="key"></param> 
    /// <param name="value"></param> 
    public static void SetValue(string key, object value) 
    { 
     if (_values.ContainsKey(key)) 
     { 
      _values.Remove(key); 
     } 
     _values.Add(key, value); 
    } 

    /// <summary> 
    /// Gets the object with the associated entered key. 
    /// </summary> 
    /// <typeparam name="T"></typeparam> 
    /// <param name="key"></param> 
    /// <returns></returns> 
    public static T GetValue<T>(string key) 
    { 
     if (_values.ContainsKey(key)) 
     { 
      return (T)_values[key]; 
     } 
     else 
     { 
      return default(T); 
     } 
    } 

    /// <summary> 
    /// Clears all values from the ApplicationState 
    /// </summary> 
    public static void ClearValues() 
    { 
     _values.Clear(); 
    } 

    /// <summary> 
    /// Checks if the dictionary contains a value with a key equal to the entered string 
    /// </summary> 
    /// <param name="key"></param> 
    /// <returns></returns> 
    public static bool ContainsValue(string key) 
    { 
     if (_values.ContainsKey(key)) 
     { 
      return true; 
     } 
     else 
     { 
      return false; 
     } 
    } 

    /// <summary> 
    /// Gets all values currently saved within the ApplicationState, in the form of a dictionary(string, object) 
    /// </summary> 
    /// <returns></returns> 
    public static Dictionary<string, object> GetAllValues() 
    { 
     return _values; 
    } 

    /// <summary> 
    /// Removes a KeyValuePair from the dictionary where the key equals the entered string 
    /// </summary> 
    /// <param name="key"></param> 
    public static void Remove(string key) 
    { 
     _values.Remove(key); 
    } 

    /// <summary> 
    /// Removes all KeyValuePairs from the dictionary where the key starts with entered string 
    /// </summary> 
    /// <param name="startsWith"></param> 
    public static void RemoveStartsWith(string startsWith) 
    { 
     var toRemove = _values.Where(x => x.Key.StartsWith(startsWith)) 
        .Select(pair => pair.Key) 
        .ToList(); 

     foreach (var key in toRemove) 
     { 
      _values.Remove(key); 
     } 
    } 
} 

die Daten werden dann eingestellt, indem die Verwendung von folgenden:

ApplicationState.SetValue("MyKey", ObjectToStore); 

und es zurückzuholen Sie einfach verwenden:

ApplicationState.GetValue<ObjectToStore>("MyKey"); 

Edit:

Also yo Sie können das Objekt/die Variable aus dem Wörterbuch ziehen, es ändern, hinzufügen etc. und es dann einfach wieder unter den gleichen Schlüssel einfügen, Sie können dies auf der Seite ändern, klicken Sie auf, wie auch immer Sie wollen. Es ist wirklich sehr einfach und vielseitig.

Einfache int und Objekt Beispiel angefordert als

Speichern eines int:

int i = 10 

ApplicationState.SetValue("ThisIsANumber", i); 

oder

ApplicationState.SetValue("ThisIsANumber", 10); 

Abrufen einer Int

int variable = ApplicationState.GetValue<int>("ThisIsANumber"); 

Speicher ein Objekt

Object obj; 

ApplicationState.SetValue("ThisIsAnObject", obj); 

ein Objekt abrufen

Object theObject = ApplicationState.GetValue<Object>("ThisIsAnObject"); 
+1

Das sieht gut aus. Also habe ich recht, wenn ich sage, dass Sie diesen Code in eine Datei im gemeinsamen Projekt eingefügt haben, und es kann verwendet werden. – Alan2

+1

@Alan yep es ist bereit zu gehen, wie es ist, ich benutze es in den meisten unserer Cross-Plattform-Anwendungen, weil es so generisch und einfach zu implementieren ist. Versteht mich nicht falsch, es wird nicht in jeder Situation perfekt sein, aber es löst auf jeden Fall viele Probleme mit der Weitergabe von Daten zwischen Seiten/Ansichten usw. – Digitalsa1nt

+0

Wenn es Ihnen nichts ausmacht, können Sie ein Beispiel für das Speichern und Abrufen geben ein Int und ein Objekt. Nur ein paar Zeilen. Am einfachsten kannst du aufkommen. Ich hoffe, dass es auch anderen helfen kann, da ich schon vorher darüber geschrieben habe, aber keine gute Antwort bekommen habe, bis ich die Frage ein wenig geändert habe. – Alan2

2

Aber Sie könnten es jedes Mal an einen Konstruktor übergeben, ich denke, es wäre besser, eine statische Singleton-Klasse zum Speichern der 'gemeinsamen' Werte zu erstellen. Dann müssen Sie es nicht immer weitergeben, aber Sie haben nur einen Aufruf an die Klasse machen zu füllen/get Werte

ein bisschen mehr Informationen über Singletons/statische Klassen: https://www.dotnetperls.com/singleton-static

ein Beispiel:

die statische Klasse, wo wir unsere Werte gehen zu halten in: öffentliche statische Klasse Test {

public static Person person; 

    static Test() 
    { 

    } 

    public static void ResetValues() { 
     person= new Person(); 
    } 
} 

als in Ihrer Hauptseite (vergessen Sie nicht mit statischen Test (= Name der Klasse) hinzugefügt werden): von sowieso (rufen Sie einfach Person aus der

public MainPage() 
    { 
     InitializeComponent(); 
//person --> comes from the static class 

    person=new Person() 
    { 
     Name = "Han Solo", 
     Age = 39 
    }; 

    var phrasesPage = new NavigationPage(new PhrasesPage()) 
    { 
     Title = "Play", 
     Icon = "play.png" 
    }; 
    .... 
    .... 
    Children.Add(phrasesPage); 
    Children.Add(categoriesPage); 
    Children.Add(favoritesPage); 
    Children.Add(settingsPage); 
    Children.Add(aboutPage); 
} 

als Sie han acces Solo kann statische Klasse)

+0

Wenn möglich können Sie ein Beispiel mit nur 5-6 Zeilen Code bis zu mir helfen, was Sie meinen. Übrigens habe ich der Frage ein wenig hinzugefügt, vielleicht macht das jetzt mehr Sinn. – Alan2

+1

@Alan Ich mache ein Beispiel mit einer statischen Klasse, da ich mehr daran gewöhnt bin –

+1

Ich habe den Beispielcode hinzugefügt –

Verwandte Themen