如何在Windows Phone运行时更改内置PhoneAccentColor?

时间:2013-11-24 08:01:03

标签: silverlight windows-phone-7 windows-phone-8 windows-phone resourcedictionary

我正在玩这个很棒的助手Windows Phone Theme Manager,以便用户可以从手机的内置颜色中指定不同的强调色。

然而,我发现的是方法

ThemeManager.SetAccentColor(AccentColor.Red);
当我在xaml中使用Color资源而不是Brush资源时,

无效。例如,下面的第一个Grid仍然使用手机的强调色;而第二个使用我在SetAccentColor方法中定义的任何内容。

<Grid x:Name="NotWorking">
    <Grid.Background>
        <SolidColorBrush Color="{StaticResource PhoneAccentColor}"/>
    </Grid.Background>
</Grid>

<Grid x:Name="WorkingFine" Background="{StaticResource PhoneAccentBrush}"/>

问题似乎出现在下面的特定方法中(在这种情况下,prefix“PhoneAccent”)。由于Color资源是值类型,因此更改currentColor对实际资源没有任何影响。

internal static void SetOrCreateColorAndBrush(string prefix, Color color)
{
    var currentColor = new Color();
    // Check if the Colour is actually in the dictionary
    if (Application.Current.Resources.Contains(prefix + "Color"))
    {
        currentColor = (Color)Application.Current.Resources[prefix + "Color"];
        currentColor.A = color.A;
        currentColor.B = color.B;
        currentColor.G = color.G;
        currentColor.R = color.R;
    }

然后我尝试将资源直接设置为color -

Application.Current.Resources[prefix + "Color"] = color;

后来我才发现,由于this,这也行不通。

我的最后一次尝试是从Application.Current.Resources中删除此资源,然后使用color值重新添加该资源。但由于某种原因,我不知道,即使在Remove方法之后,仍然可以在资源中找到此资源......

Application.Current.Resources.Remove(prefix + "Color");
var stilReturnsTrue = Application.Current.Resources.Contains(prefix + "Color");

我在这里有点想法。不知道有没有人遇到这个并找到了解决办法吗?

2 个答案:

答案 0 :(得分:1)

如果可能的话,第一个选项是仅在任何地方使用PhoneAccentBrush。

我建议的另一个选项是在ViewModel 中使用您自己的Color类型属性,该属性将在使用DataBinding的所有适当位置使用。
在开始时,您使用Application.Current.Resources中的当前强调颜色设置此属性,稍后您可以根据需要更改此值,它将按预期传播到所有使用它的位置。
这里唯一的问题是你不能在动画中使用这种颜色,因为动画需要固定值或静态资源。

// in "MVVM Light (PCL)" class ObservableObject
public Color MyPhoneAccentColor
{
    get { return myPhoneAccentColor; }
    set { Set(ref myPhoneAccentColor, value); }
}
private Color myPhoneAccentColor;

// in XAML
<Grid x:Name="NotWorking">
    <Grid.Background>
        <SolidColorBrush Color="{Binding MyPhoneAccentColor}"/>
    </Grid.Background>
</Grid>

答案 1 :(得分:1)

我已经编写并删除了以下代码:

    private void myButton_Click(object sender, RoutedEventArgs e)
    {
       Color myColor = (Color)App.Current.Resources["PhoneAccentColor"];
       App.Current.Resources.Remove("PhoneAccentColor");
       bool contains = App.Current.Resources.Contains("PhoneAccentColor");
       App.Current.Resources.Add("PhoneAccentColor", Colors.Brown);
       Color myCol = (Color)App.Current.Resources["PhoneAccentColor"];
       // Below works
       LayoutRoot.Background = new SolidColorBrush((Color)App.Current.Resources["PhoneAccentColor"]);
       // Not working as you have to change Brush separately
       LayoutRoot.Background = (Brush)App.Current.Resources["PhoneAccentBrush"];
       // Now working
       App.Current.Resources.Add("PhoneAccentBrush", new SolidColorBrush(Colors.Cyan));
       LayoutRoot.Background = (Brush)App.Current.Resources["PhoneAccentBrush"];
       return;
    }

修改
它运行正常 - 但它不是你想要的资源 - 它只是创建'本地'资源,它不会影响'真正的'PhoneAccentBrush - 如果你从StaticResource创建一个带有Background的新页面,它将拥有默认的PhoneAccentBrush。 /> 但我设法做到了:

  private void myButton_Click(object sender, RoutedEventArgs e)
  {
     Color myColor = (Color)App.Current.Resources["PhoneAccentColor"];
     myColor.A = 255;
     myColor.B = 75;
     myColor.G = 150;
     myColor.R = 150;
     SolidColorBrush internalBrush = (SolidColorBrush)App.Current.Resources["PhoneAccentBrush"];
     internalBrush.Color = myColor;
     return;
  }

您无法删除或覆盖PhoneAccentBrush,但“本地”(对于您的应用)您可以更改其属性。它工作得很好 - 在这个Clisk事件之后,当我创建新的Page时,PhoneAccentBrush就像我设置它一样。