我在Windows Phone 8.1应用程序中有一个页面,其中有一些组件应该能够具有三种不同的颜色状态。它们应该是红色,蓝色或当前主题的前景色。
因此,如果我的应用程序是在手机上使用Dark主题开始的,然后用户走出应用程序并更改Light主题,再次进入我的应用程序,我需要立即更改具有旧主题的前景色。
由于组件应该在不同颜色之间变换(主题的前景颜色只是其中之一),我无法将其前景设置为PhoneForegroundColor
中的XAML
。
我所做的是添加一个执行此操作的Resuming
事件监听器:
myTextBlock.Foreground = new SolidColorBrush((Color)Application.Current.Resources["PhoneForegroundColor"]);
但是......在更新Application.Current的资源之前触发了Resuming
事件,因此我最终得到了与以前相同的颜色。如果用户再次退出,则会在上次Application.Current.Resources["PhoneForegroundColor"]
事件之后的某个时间点Resuming
更新后继续工作。
问题:我什么时候可以先阅读更新的Application.Current.Resources["PhoneForegroundColor"]
,因为Resuming
似乎不是正确的地方?
问题或者,myTextBlock
是否有办法继承另一个组件的ForegroundColor(CSS-ish),这样我就可以以编程方式更改myTextBlock.Foreground
之间的红色/蓝/继承而不必在我的应用生命周期内更改手机主题?
任何建议都赞赏!
答案 0 :(得分:2)
关于你的第一个问题:“恢复过程”没有正式记录,但我想出了以下内容:
在UI线程上调用Resume。因为它是一个void返回方法,所以当它在内部等待时,调用者将继续。如果您将某些内容编组到UI线程中,它将位于调度程序队列中,因此在当前任务(恢复)之后运行。
所以我做了这个(它的作品^^):
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());
}
关于你的第二个问题:你可以在你的app.xaml中引入一个“ValueProvider”,它注册resume事件,只提供一个具有当前颜色的依赖属性。
您仍然需要在要使用的任何TextBlock上设置它,但至少直接在XAML中。这可能也适用于样式,但没有尝试。
示例实施....
提供者:
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}}" />
答案 1 :(得分:1)
在Windows Phone 8.1中,您可以通过Application.Current.RequestedTheme
确定所选主题,并返回枚举Windows.UI.Xaml.ApplicationTheme
的值。
示例:
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";
}
旁注:您甚至可以使用Application.Current.RequestedTheme
更多详情:https://msdn.microsoft.com/en-us/library/windows/apps/windows.ui.xaml.application.requestedtheme
答案 2 :(得分:0)
注册到App_Resuming对我不起作用,因为在未暂停应用程序时不会引发此事件。我不得不听Window.Current.CoreWindow.VisibilityChanged += CoreWindow_VisibilityChanged;
此解决方案无需Task.Delay
。