我正在玩这个很棒的助手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");
我在这里有点想法。不知道有没有人遇到这个并找到了解决办法吗?
答案 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就像我设置它一样。