Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien

[C# WP8] Werken met classes

Pagina: 1
Acties:

  • Douweegbertje
  • Registratie: Mei 2008
  • Laatst online: 30-10 12:53

Douweegbertje

Wat kinderachtig.. godverdomme

Topicstarter
Ik ben zoals je misschien zag aan voorgaande topics bezig met C#. Op zich gaat dit best redelijk maar ik kom echt van PHP. Nu gebruik ik ook wel OOP met PHP echter merk ik toch nog wat verschillen. Mijn grootste probleem zit hem in de " app life cycle" om het dan maar een mooi naampje te geven :+. Ik ben natuurlijk gewent om een bestand te hebben die iets afloopt en thats it.

Nu zit ik dus in C# met een app die in feite altijd blijft lopen en op hele andere manieren ' stopt' en dingen moet doen. Op dit moment zit ik met iets, waarbij zelfs na uitvoerig zoeken ik niets wijzer wordt.

Het gaat hier dus om een windows phone 8 App in C#, hier zit dus een bepaalde ' Application' pagina in als een soort van root.

app.xaml

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<Application
    x:Class="CookieClicker.App"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
    xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone">

    <!--Application Resources-->
    <Application.Resources>
        <local:LocalizedStrings xmlns:local="clr-namespace:CookieClicker" x:Key="LocalizedStrings"/>
    </Application.Resources>

    <Application.ApplicationLifetimeObjects>
        <!--Required object that handles lifetime events for the application-->
        <shell:PhoneApplicationService
            Launching="Application_Launching" Closing="Application_Closing"
            Activated="Application_Activated" Deactivated="Application_Deactivated"/>
    </Application.ApplicationLifetimeObjects>

</Application>


Hierin zitten zoals je ziet wat lifetime objects in. Deze worden weer opgevangen in de bijbehorende app.xaml.cs

kleine snipit hier;

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
 public partial class App : Application
    {

      public static PhoneApplicationFrame RootFrame { get; private set; }

 // Code to execute when the application is launching (eg, from Start)
        // This code will not execute when the application is reactivated
        private void Application_Launching(object sender, LaunchingEventArgs e)
        {

        }

        // Code to execute when the application is activated (brought to foreground)
        // This code will not execute when the application is first launched
        private void Application_Activated(object sender, ActivatedEventArgs e)
        {

        }
 // Code to execute when the application is deactivated (sent to background)
        // This code will not execute when the application is closing
        private void Application_Deactivated(object sender, DeactivatedEventArgs e)
        {
              
        }

        // Code to execute when the application is closing (eg, user hit Back)
        // This code will not execute when the application is deactivated
        private void Application_Closing(object sender, ClosingEventArgs e)
        {
           
        }

//etc


Goed, alles leuk en wel, maar mijn main app werkt gewoon in een Game.xaml met de bijbehorende game.xaml.cs. Hier laad ik ook wat game data via een settings class

C#:
1
 private Settings settings = new Settings();


En hier worden ook de event handlers e.d. neer gezet. In feite werkt dit allemaal prima totdat ik iets moet gaan doen met mijn data als een event gebeurt zoals Application_Closing.

Deze data (uit mijn settings class) is geïnitieerd in mijn game. Bepaalde waardes werden uit de localstorage gehaald, en indien iemand speelt zijn deze waardes natuurlijk veranderd. Op het moment van een app_closing moet ik in feite mijn class benaderen om deze data dan weer te setten in de storage.

Het probleem, of het geen wat ik nu niet snap ik het feit dat ik deze data / object / class niet kan benaderen. Simpelweg een nieuwe class aanroepen geeft mij een ander object natuurlijk.

Om het nog kort samen te vatten:

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
 public partial class Game : PhoneApplicationPage
    {

        private Settings settings = new Settings();
        int CookieCount;
        

        public Game()
        {
            InitializeComponent();
            CookieCount = settings.CookieCountSetting;


// vervolgens doe ik allerlei dingen met de CookieCount

// Om uiteindelijk deze data (CookieCount) op te slaan gooi ik hem weer terug met;

 settings.CookieCountSetting = CookieCount;


Nu is het de bedoeling dat dit in de App.xaml.cs komt te staan, echter zijn deze events niet(?) toegankelijk binnen mijn Game.xaml , noch game.xaml.cs

De game.xaml gebruikt het volgende

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<phone:PhoneApplicationPage
    x:Class="CookieClicker.Game"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
    xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    FontFamily="{StaticResource PhoneFontFamilyNormal}"
    FontSize="{StaticResource PhoneFontSizeNormal}"
    Foreground="{StaticResource PhoneForegroundBrush}"
    SupportedOrientations="PortraitOrLandscape" Orientation="Portrait"
    mc:Ignorable="d"
    shell:SystemTray.IsVisible="True">


Waar dus die events niet in kunnen, dat is puur in de App.

Ik hoop dat ik enigszins duidelijk ben (waarschijnlijk niet -O- ) maar kan iemand mij wat dingen uitleggen en het liefst wat links geven naar resources zodat ik eens fatsoenlijk kan lezen hoe je dingen goed opzet. Ik heb mij sinds gister al lam gezocht, en ik heb nergens goede guides kunnen vinden. Ik heb zelfs -alle- voorbeelden van de win8 apps gedownload, maar nergens zie ik een reference met wat ik wil.

Het gaat hier ook vooral om het op de juiste manier te doen, ik heb bijvoorbeeld nu al een dodgy manier om bij elke change dit direct in de localstorage te gooien. Mij lijkt het echter niet ' goed' om elke seconden een waarde daarin te gaan gooien.

  • BikkelZ
  • Registratie: Januari 2000
  • Laatst online: 21-02 08:50

BikkelZ

CMD+Z

De boerenlul methode voor het oplossen van dit soort problemen is meestal een singleton pattern. Want je wil het maar één keer initialiseren en overal kunnen benaderen. Het kan zijn dat er hoop mensen foeibah zeggen en voor het benaderen van applicatiesettings is volgens mij onder de meeste Microsoft frameworks meestal een betere standaardmethode.

Met een korte zoektocht kwam ik dit tegen:
MSDN: Quickstart: Working with settings in Windows Phone
http://blogs.msdn.com/b/g...windows-8-store-apps.aspx

[ Voor 11% gewijzigd door BikkelZ op 26-10-2013 21:32 ]

iOS developer


  • Douweegbertje
  • Registratie: Mei 2008
  • Laatst online: 30-10 12:53

Douweegbertje

Wat kinderachtig.. godverdomme

Topicstarter
De links die je geeft is vrijwel identiek aan wat ik heb. Dingen in de IsolatedStorage zetten (noemde het per ongeluk localstorage) is ook het probleem niet. Het probleem zit hem in het feit dat ik dit (nog) niet kan doen wanneer de app sluit. Op dit moment doe ik het dan maar om de 10 seconden, binnen mijn class. Eigenlijk wil ik dit in deze soort 'core class' doen (App.xaml.cs) omdat hier de events van de start/stop app zitten.

Tenzij iemand mij kan vertellen of het benaderen van de Isolated storage elke seconde geen kwaad kan?

  • BikkelZ
  • Registratie: Januari 2000
  • Laatst online: 21-02 08:50

BikkelZ

CMD+Z

Ah okee je wil eerst alles in normale objecten opslaan tot je de state wil saven bij bijvoorbeeld een Application_Closing event. Buiten het feit dat een singleton pattern zou werken zijn er waarschijnlijk ook manieren om in die functie zaken te benaderen. Ik ben nu toevallig met een iOS app bezig en daar moet ik een timer door laten lopen op het moment dat je de applicatie sluit.

Ik kan in dat geval de application variabele uitlezen omdat die meegestuurd wordt maar ook kan ik de main ViewController aanroepen, casten naar mijn implementatie en uitlezen.

Dit moet ook mogelijk zijn bij Windows Phone. Denk aan het casten van de sender bijvoorbeeld, wellicht iets in de EventArgs of je kunt via de Application class wat variabelen benaderen via self.

Ik zoek nog even verder voor je.

----------

Bekijk even: MSDN: Application Class (System.Windows)
Je kunt bijvoorbeeld de MainWindow aanroepen. Echter is het in de MVC-variant bij iOS wat normaler om zo in je ViewController te duiken, bij Windows Phone is dat misschien niet de manier:

MSDN: Application.MainWindow Property (System.Windows)

----------

Het proces heet in WP8 termen "tombstoning" en er is best veel over te vinden, ook op MSDN:
MSDN: How to preserve and restore app state for Windows Phone

[ Voor 32% gewijzigd door BikkelZ op 26-10-2013 23:48 ]

iOS developer


  • Caelorum
  • Registratie: April 2005
  • Laatst online: 14:18
Kijk even of je niet een instance van de settings class via een resource file beschikbaar kan maken. Die gebruik je dan in zowel je pages als de Application class. Dit is bijvoorbeeld hoe ze het in MVVMLight doen. Sowieso is dat een mooi framework om naar te kijken, is het niet om te gebruiken, dan wel om te zien hoe zij dit soort dingen op lossen. Heeft mij bij het beginnen met ontwikkelen voor Windows Phone enorm geholpen.

[ Voor 4% gewijzigd door Caelorum op 27-10-2013 00:06 ]


  • BikkelZ
  • Registratie: Januari 2000
  • Laatst online: 21-02 08:50

BikkelZ

CMD+Z

Caelorum schreef op zondag 27 oktober 2013 @ 00:00:
Kijk even of je niet een instance van de settings class via een resource file beschikbaar kan maken. Die gebruik je dan in zowel je pages als de Application class. Dit is bijvoorbeeld hoe ze het in MVVMLight doen. Sowieso is dat een mooi framework om naar te kijken, is het niet om te gebruiken, dan wel om te zien hoe zij dit soort dingen op lossen. Heeft mij bij het beginnen met ontwikkelen voor Windows Phone enorm geholpen.
Ik denk dat de echte vraag is hoe je van tijdelijke naar permantente opslag van je applicatie data en weer terug gaat op het moment dat iemand zijn applicatie minimaliseert. Je wil niet steeds je permanente opslag raken op het moment dat je weer 10 punten gescoord hebt in een schietspelletje.

Bij internet applicaties ga je altijd via de database wat je ook doet. Bij desktop en mobile applicaties niet.

iOS developer


  • Caelorum
  • Registratie: April 2005
  • Laatst online: 14:18
Het punt is denk ik dat hij alles al wel heeft, maar geen idee heeft van hoe hij vanuit de functies in Application ding in de class waar hij alle data heeft moet aanroepen. De methode die ik heb genoemd werkt zeker wel. Daarnaast vermoed ik dat er meer mis is qua architectuur in zijn code al is dat zonder de complete code te zien wat lastig echt vast te stellen. Zelf ben ik overigens enorm fan van MVVM in situaties waar xaml mee gemoeid is. Hoe dan ook zal het kijken naar een voorbeeld app (staat een op die site in een nieuwspost) waarin MVVMLight wordt gebruikt op meerdere manieren helpen om een begrip te vormen van hoe bepaalde dingen voor elkaar te krijgen.

  • Douweegbertje
  • Registratie: Mei 2008
  • Laatst online: 30-10 12:53

Douweegbertje

Wat kinderachtig.. godverdomme

Topicstarter
De App.xaml is een soort van 'core' die alles doet qua App. Dit staat los van mijn pagina's, maar draait wel OM een pagina heen. Je hebt dus je App draaien EN je pagina waar je zit.
De App.xaml is dus het enige wat iets kan doen met de Application_Closing event. Zie het als je core van je App.

Alles draait dus wel goed, ik heb ook gewoon alle data. Echter draait er gewoon een class in mijn 'game' terwijl ik juist een score moet gaan opslaan van deze class als mijn app sluit. Dan moet ik dus opeens vanuit mijn phone: pagina naar de app; om dit te gaan doen.

Ik zal anders zo wel de gehele code posten.

edit:

Even op github gepleurd ;

https://github.com/douweegbertje/cookieclicker

Zoals je ziet heb ik nu gewoon een timer lopen die het om de 5 seconden saved. Juist die save wil ik niet per X seconden doen, maar pas als het spel sluit.

[ Voor 16% gewijzigd door Douweegbertje op 27-10-2013 11:59 ]


  • Caelorum
  • Registratie: April 2005
  • Laatst online: 14:18
Dus als ik het goed begrijp wil je een manier hebben om die Application_Closing door te zetten naar je 'game' class, zonder dat er een directe referentie is naar je 'game' class in App?

Wat je dan zou kunnen doen is een event aanmaken in je App class
C#:
1
2
3
4
5
6
7
8
9
10
11
        public event EventHandler application_Closing;

        // Code to execute when the application is closing (eg, user hit Back)
        // This code will not execute when the application is deactivated
        private void Application_Closing(object sender, ClosingEventArgs e)
        {
            if (application_Closing != null)
                application_Closing(this, null);

            ViewModelLocator.Cleanup(); //Deze zul je wellicht niet daar hebben staan :)
        }


In je game class voeg je dan ergens
C#:
1
            ((App)Application.Current).application_Closing += MainPage_application_Closing;

toe, bijvoorbeeld in je constructor. En de volgende method
C#:
1
2
3
4
          void MainPage_application_Closing(object sender, EventArgs e)
        {
            throw new NotImplementedException(); //jouw code die je wil uitvoeren hier
        }


Dat kan je dan uiteraard ook voor de andere zooi doen.

  • Douweegbertje
  • Registratie: Mei 2008
  • Laatst online: 30-10 12:53

Douweegbertje

Wat kinderachtig.. godverdomme

Topicstarter
ah dit is geweldig :)
Ik snap nu ook wat je doet, en het werkt ook gewoon perfect!

Super bedankt!

  • Caelorum
  • Registratie: April 2005
  • Laatst online: 14:18
De andere mogelijkheid die nog best vaak wordt gebruikt is je view te binden aan een viewmodel die gedefinieerd is in een class (viewmodellocator in MVVMLight). Die ViewModelLocator initialiseer je dan in een resourcedictionary. En vanuit je Application class kan je dan in 1 keer alle ViewModels zichzelf netjes laten opruimen. Nu moet je namelijk ook als je weg navigeert naar een andere pagina dingen opslaan. Op die manier kan je alle ViewModels laten bestaan en in 1 keer alles opslaan bij het afsluiten van de App. Het MVVM pattern is in WP eigenlijk gewoon the way to go tenzij je bijv. maar 1 pagina hebt zoals met spellen vaak het geval.

  • Douweegbertje
  • Registratie: Mei 2008
  • Laatst online: 30-10 12:53

Douweegbertje

Wat kinderachtig.. godverdomme

Topicstarter
Caelorum schreef op zondag 27 oktober 2013 @ 16:26:
De andere mogelijkheid die nog best vaak wordt gebruikt is je view te binden aan een viewmodel die gedefinieerd is in een class (viewmodellocator in MVVMLight). Die ViewModelLocator initialiseer je dan in een resourcedictionary. En vanuit je Application class kan je dan in 1 keer alle ViewModels zichzelf netjes laten opruimen. Nu moet je namelijk ook als je weg navigeert naar een andere pagina dingen opslaan. Op die manier kan je alle ViewModels laten bestaan en in 1 keer alles opslaan bij het afsluiten van de App. Het MVVM pattern is in WP eigenlijk gewoon the way to go tenzij je bijv. maar 1 pagina hebt zoals met spellen vaak het geval.
Ik heb inderdaad maar 'één' pagina, buiten het startscherm en eventueel andere non-boeiende schermpjes. Ik zal eens dat MVVM pattern opzoeken en wellicht voor een volgende app gebruiken!

Ook jij bedankt voor je hulp trouwens! :Y)

  • Caelorum
  • Registratie: April 2005
  • Laatst online: 14:18
Als je meer wilt weten over mvvm is deze Video een mooie start: http://channel9.msdn.com/...el-view-viewmodel-pattern
Pagina: 1