【问题标题】:How to change built-in PhoneAccentColor during runtime on Windows Phone?如何在 Windows Phone 运行时更改内置的 PhoneAccentColor?
【发布时间】:2013-11-24 08:01:02
【问题描述】:

我正在使用这个很棒的助手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");

我有点想不通了。想知道是否有人遇到过这种情况并找到任何解决方法?

【问题讨论】:

  • 您在 XAML 中关于颜色与画笔的问题是因为您使用 StaticResource 绑定到颜色和画笔。 StaticResource 可以监听对象内属性的变化(Brush 的 Color 属性),但不能监听对象本身。
  • @emedbo,我认为问题根本不在于StaticResource。问题是如何设置值,而不是如何更新 UI 上的值。请注意,Brush 工作正常。

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


【解决方案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,但是我不能接受这个作为答案,因为我特别需要它用于动画......
  • 我认为您根本无法更改在 XAML 中定义的动画的颜色 - 它们使用固定值。除非您在需要时以编程方式创建所有动画。
  • 我在ColorAnimation 中将它们用作StaticResource。例如&lt;ColorAnimation To={StaticResource PhoneAccentColor} ... /&gt; 你知道吗,因为ToFrom 属性确实是一个依赖属性,我实际上可以使用绑定为它们设置动画!如果您稍微修改一下答案,我会很乐意接受它作为答案。 :)
【解决方案2】:

我已经编写并调试了以下代码:

    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 创建具有背景的新页面,它将具有默认的 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 事件之后,当我创建新页面时,PhoneAccentBrush 就像我设置的那样。

【讨论】:

  • +1,有趣!我刚刚测试过,Add 确实覆盖了原来的,但是如果您在 xaml 中定义了颜色资源,它仍然会出于某种原因显示默认的强调色。但是,如果我尝试自定义颜色,则效果很好...
  • @Xin 经过一番思考,我编辑了我的帖子。有一种方法可以影响 xaml 中的颜色。
  • 是的,Brush 可以正常工作,就像我在帖子中所说的那样,但是如果您尝试更改 xaml 中的 Color,您根本就做不到。我认为唯一的方法是在资源中创建自己的Color...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多