2015-01-04 13 views
5

Ho una pagina in un'app di Windows Phone 8.1 in cui ho alcuni componenti che dovrebbero essere in grado di avere tre diversi stati di colore. Dovrebbero essere rossi, blu o il colore di primo piano del tema corrente.Quando controllare a livello di programmazione le modifiche ai temi in Windows Phone 8.1

Pertanto, se la mia app viene avviata utilizzando il tema Dark sul telefono, quindi l'utente esce dall'app e cambia il tema Light e accede di nuovo alla mia app, ho bisogno di cambiare immediatamente i componenti che avevano il colore di primo piano del vecchio tema.

Poiché i componenti devono cambiare tra diversi colori (in cui il colore di primo piano del tema è solo uno di essi) non è possibile impostare il Primo piano su PhoneForegroundColor in XAML.

Quello che ho fatto è quello di aggiungere un listener Resuming evento che fa questo:

myTextBlock.Foreground = new SolidColorBrush((Color)Application.Current.Resources["PhoneForegroundColor"]); 

Ma ... l'evento Resuming viene generato prima le risorse del Application.Current sono aggiornati, così finisco con lo stesso colore di prima. Se l'utente esce nuovamente e di nuovo, funzionerà dal momento che il Application.Current.Resources["PhoneForegroundColor"] è stato aggiornato ad un certo punto dopo l'evento Resuming la volta precedente.

Domanda: Quando posso leggere prima la versione aggiornata Application.Current.Resources["PhoneForegroundColor"], dal momento che Resuming non sembra essere il posto giusto?

Domanda: In alternativa, c'è un modo per myTextBlock ereditare ForegroundColor (CSS-ish) di un altro componente, in modo che possa cambiare la myTextBlock.Foreground programatically tra rosso/blu/Eredita senza dover mente modifiche al telefono Theme nel ciclo di vita della mia app?

Qualsiasi suggerimento apprezzato!

risposta

2

Per quanto riguarda la prima domanda: Il "processo Resume" non è ufficialmente documentato, ma ho capito quanto segue:

Riprendi viene chiamato sul thread dell'interfaccia utente. Dato che è un metodo di restituzione del vuoto, il chiamante continuerà solo quando avrà l'attesa dentro. Se si esegue il marshalling di qualcosa nel thread dell'interfaccia utente, si troverà nella coda del dispatcher e quindi verrà eseguito dopo l'attività corrente (ripresa).

Così ho appena fatto questo (e funziona ^^):

private async void App_Resuming(object sender, object e) 
{ 

    var x1 = new SolidColorBrush((Color)Application.Current.Resources["PhoneForegroundColor"]); 
    Debug.WriteLine(x1?.Color.ToString()); 

    // Await marshalls back to the ui thread, 
    // so it gets put into the dispatcher queue 
    // and is run after the resuming has finished. 
    await Task.Delay(1); 

    var x2 = new SolidColorBrush((Color)Application.Current.Resources["PhoneForegroundColor"]); 
    Debug.WriteLine(x2?.Color.ToString()); 
} 

quanto riguarda la tua seconda domanda: Si potrebbe introdurre un "ValueProvider" nella vostra app.xaml, che registra per l'evento di ripresa e fornisce solo una proprietà di dipendenza con il colore corrente.

Sarà comunque necessario impostarlo su qualsiasi TextBlock in cui si desidera utilizzarlo, ma almeno direttamente in XAML. Questo potrebbe funzionare anche per gli stili, ma non l'ho provato.

realizzazione di esempio ....

Provider:

public class ColorBindingProvider : DependencyObject 
{ 
    public ColorBindingProvider() 
    { 
     App.Current.Resuming += App_Resuming; 
    } 

    private async void App_Resuming(object sender, object e) 
    { 
     // Delay 1ms (see answer to your first question) 
     await Task.Delay(1); 

     TextColor = new SolidColorBrush((Color)Application.Current.Resources["PhoneForegroundColor"]); 
    } 

    public Brush TextColor 
    { 
     get { return (Brush)GetValue(TextColorProperty); } 
     set { SetValue(TextColorProperty, value); } 
    } 

    public static readonly DependencyProperty TextColorProperty = 
     DependencyProperty.Register("TextColor", typeof(Brush), typeof(ColorBindingProvider), new PropertyMetadata(null)); 
} 

App.XAML:

<Application.Resources> 
    <local:ColorBindingProvider x:Name="ColorBindingProvider" TextColor="{StaticResource PhoneForegroundBrush}" /> 
</Application.Resources> 

MainPage.xaml:

<TextBlock Text="Hey ho let's go" Foreground="{Binding TextColor, Source={StaticResource ColorBindingProvider}}" /> 
+0

Grazie mille! Ho anche ottenuto il primo a lavorare così vado con quella soluzione :) Per la soluzione alternativa, però, avrei bisogno di impostare il Primo piano su "{Binding TextColor, Source = {StaticResource ColorBindingProvider}}" giusto? Dal momento che potrei averlo sovrascritto con Red o Blue, quindi tutto ciò che era nello XAML non è più attivo ... – andrrs

+0

No, puoi semplicemente mettere le impostazioni del colore nel metodo "App_Resuming" del provider. È una proprietà di dipendenza, quindi notificherà tutte le associazioni durante l'aggiornamento. Ovviamente devi attivarlo in qualche modo, se cambi le impostazioni del colore in fase di esecuzione. Utilizzare la messaggistica o semplicemente ottenere il provider tramite App.Current.Resources [...] e impostare la proprietà. –

+0

Btw: invece di usare una proprietà di dipendenza, si potrebbe anche semplicemente avere BindingProvider implementare INotifyPropertyChanged ... –

1

In Windows Phone 8.1 si è in grado di determinare il tema selezionato tramite Application.Current.RequestedTheme strega restituirà un valore della enum Windows.UI.Xaml.ApplicationTheme.

esempio:

public static string GetImagePath(){ 
    // if the background color is black, i want a white image 
    if(Application.Current.RequestedTheme == ApplicationTheme.Dark) 
     return "ms-appx:///Assets/img_light.jpg"; 

    // if the background color is white, i want a dark image 
    return "ms-appx:///Assets/img_dark.jpg"; 
} 

nota a margine: si è nemmeno in grado di cambiare il tema selezionato con Application.Current.RequestedTheme

maggiori dettagli: https://msdn.microsoft.com/en-us/library/windows/apps/windows.ui.xaml.application.requestedtheme

0

Registra per App_Resuming non ha funzionato per me, perché questo l'evento non viene generato quando l'applicazione non è sospesa. Ho dovuto ascoltare Window.Current.CoreWindow.VisibilityChanged += CoreWindow_VisibilityChanged;

Non c'è bisogno di Task.Delay con questa soluzione.

Problemi correlati