何时以编程方式检查Windows Phone 8.1中的主题更改

and*_*rrs 5 c# xaml windows-phone windows-phone-8.1

我在Windows Phone 8.1应用程序中有一个页面,其中有一些组件应该能够具有三种不同的颜色状态.它们应该是红色,蓝色或当前主题的前景色.

因此,如果我的应用程序是在手机上使用Dark主题开始的,然后用户走出应用程序并更改Light主题,再次进入我的应用程序,我需要立即更改具有旧主题前景的组件颜色.

由于部件都应该不同的颜色之间切换(其中主题的前景色只是其中之一),我不能将其前景设为PhoneForegroundColorXAML.

我所做的是添加一个Resuming执行此操作的事件侦听器:

myTextBlock.Foreground = new SolidColorBrush((Color)Application.Current.Resources["PhoneForegroundColor"]);
Run Code Online (Sandbox Code Playgroud)

但是...... Resuming事件在Application.Current的资源更新之前被触发,所以我最终得到了和以前一样的颜色.如果用户再次退出,那么它将在上一次事件发生Application.Current.Resources["PhoneForegroundColor"]后的某个时刻更新Resuming.

问:我什么时候可以先阅读更新Application.Current.Resources["PhoneForegroundColor"],因为Resuming似乎不是正确的地方?

问题:或者,有没有办法myTextBlock继承另一个组件的ForegroundColor(CSS-ish),这样我就可以myTextBlock.Foreground在Red/Blue/Inherit之间以编程方式更改,而不必在我的应用程序生命周期内更改手机主题?

任何建议赞赏!

Kai*_*und 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());
}
Run Code Online (Sandbox Code Playgroud)

关于第二个问题:您可以在 app.xaml 中引入一个“ValueProvider”,它注册恢复事件并仅提供具有当前颜色的依赖属性。

您仍然需要在要使用它的任何 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));
}
Run Code Online (Sandbox Code Playgroud)

应用程序.xaml:

<Application.Resources>
    <local:ColorBindingProvider x:Name="ColorBindingProvider" TextColor="{StaticResource PhoneForegroundBrush}" />
</Application.Resources>
Run Code Online (Sandbox Code Playgroud)

主页.xaml:

<TextBlock Text="Hey ho let's go" Foreground="{Binding TextColor, Source={StaticResource ColorBindingProvider}}" />
Run Code Online (Sandbox Code Playgroud)