我有一个空白,分析图像,提取两种主色,并取代" SystemControlForegroundAccentBrush"和#34; SystemControlHighlightAccentBrush",我在App.xaml中重写。它运行良好,除了分析图像需要一些时间,因此一旦我的页面中的所有控件都已加载,它就会改变颜色。 结果,他们保持旧的强调色。如何让它们动态绑定到ThemeRessource?
这是我的app.xaml:
$(".arrowback").live("click", function(){
var userID = this.id;
alert(userID);
});
这是改变颜色的ColorExtractor.cs类的(非常简化的)部分:
<Application.Resources>
<ResourceDictionary x:Name="resdic">
<ResourceDictionary.ThemeDictionaries>
<ResourceDictionary x:Key="Dark">
<SolidColorBrush x:Key="SystemControlForegroundAccentBrush"/>
<SolidColorBrush x:Key="SystemControlHighlightAccentBrush"/>
</ResourceDictionary>
</ResourceDictionary.ThemeDictionaries>
</ResourceDictionary>
</Application.Resources>
我在Page.xaml中有一堆控件,它们的前景设置如下:
public async static void Analyse()
{
Application.Current.Resources["SystemControlForegroundAccentBrush"] = new SolidColorBrush(color);
Application.Current.Resources["SystemControlHighlightAccentBrush"] = new SolidColorBrush(color2);
}
我在Page.xaml.cs中调用<TextBlock Foreground="{ThemeResource SystemControlForegroundAccentBrush]"/>
(在OnNavigatedTo事件中)。我总是可以创建一个在设置颜色后被触发的事件,但是我需要找到一种方法来更新页面中所有控件的颜色。
答案 0 :(得分:0)
您可以查看模板10如何进行主题更改,但在他们的情况下,他们提前在资源词典中定义了两个不同的主题。您可以在repo on Github中找到他们的代码,但以下是一些使用的代码:
(Window.Current.Content as FrameworkElement).RequestedTheme = value.ToElementTheme();
Views.Shell.SetRequestedTheme(value, UseBackgroundChecked);
来自here
public static void SetRequestedTheme(ApplicationTheme theme, bool UseBackgroundChecked)
{
WindowWrapper.Current().Dispatcher.Dispatch(() =>
{
(Window.Current.Content as FrameworkElement).RequestedTheme = theme.ToElementTheme();
ParseStyleforThemes(theme);
HamburgerMenu.NavButtonCheckedForeground = NavButtonCheckedForegroundBrush;
HamburgerMenu.NavButtonCheckedBackground = (UseBackgroundChecked) ?
NavButtonCheckedBackgroundBrush : NavButtonBackgroundBrush;
HamburgerMenu.NavButtonCheckedIndicatorBrush = (UseBackgroundChecked) ?
Colors.Transparent.ToSolidColorBrush() : NavButtonCheckedIndicatorBrush;
HamburgerMenu.SecondarySeparator = SecondarySeparatorBrush;
List<HamburgerButtonInfo> NavButtons = HamburgerMenu.PrimaryButtons.ToList();
NavButtons.InsertRange(NavButtons.Count, HamburgerMenu.SecondaryButtons.ToList());
List<HamburgerMenu.InfoElement> LoadedNavButtons = new List<HamburgerMenu.InfoElement>();
foreach (var hbi in NavButtons)
{
StackPanel sp = hbi.Content as StackPanel;
if (hbi.ButtonType == HamburgerButtonInfo.ButtonTypes.Literal) continue;
ToggleButton tBtn = sp.Parent as ToggleButton;
Button btn = sp.Parent as Button;
if (tBtn != null)
{
var button = new HamburgerMenu.InfoElement(tBtn);
LoadedNavButtons.Add(button);
}
else if (btn != null)
{
var button = new HamburgerMenu.InfoElement(btn);
LoadedNavButtons.Add(button);
continue;
}
else
{
continue;
}
Rectangle indicator = tBtn.FirstChild<Rectangle>();
indicator.Visibility = ((!hbi.IsChecked ?? false)) ? Visibility.Collapsed : Visibility.Visible;
if (!hbi.IsChecked ?? false) continue;
ContentPresenter cp = tBtn.FirstAncestor<ContentPresenter>();
cp.Background = NavButtonCheckedBackgroundBrush;
cp.Foreground = NavButtonCheckedForegroundBrush;
}
LoadedNavButtons.ForEach(x => x.RefreshVisualState());
});
}
来自here
答案 1 :(得分:0)
我有一个空白,分析图像,提取两种主色,并取代&#34; SystemControlForegroundAccentBrush&#34;和#34; SystemControlHighlightAccentBrush&#34;,我在App.xaml中重写。
首先,我不认为app.xaml中的代码可以覆盖ThemeResource
,您在页面中使用了此Brush
,如下所示:
<TextBlock Foreground="{ThemeResource SystemControlForegroundAccentBrush}" Text="Hello World!" FontSize="50" />
如果按&#34; F12&#34;在SystemControlForegroundAccentBrush
上,您可以在&#34; generic.xaml&#34;中找到此资源。文件。
现在假设您的ColorExtractor.cs
类工作正常,ColorExtractor.Analyse()
可以覆盖这两个画笔的颜色,并且页面中有很多控件使用这两个资源,刷新页面可以解决您的问题。
但我认为最好不要将此操作放在OnNavagateTo
事件或Page.Loaded
事件中,UWP中没有刷新方法,我们再次导航到此页面进行刷新,因此,如果将此操作放在OnNavagateTo
事件或Page.Loaded
事件中,则每次导航到此页面时,资源都将被覆盖并再次导航。所以我把这个操作放在这样的Button click事件中:
public bool Reload()
{
return Reload(null);
}
private bool Reload(object param)
{
Type type = this.Frame.CurrentSourcePageType;
if (this.Frame.BackStack.Any())
{
type = this.Frame.BackStack.Last().SourcePageType;
param = this.Frame.BackStack.Last().Parameter;
}
try { return this.Frame.Navigate(type, param); }
finally
{
this.Frame.BackStack.Remove(this.Frame.BackStack.Last());
}
}
private void Button_Click(object sender, RoutedEventArgs e)
{
ColorExtractor.Analyse();
Reload();
}
答案 2 :(得分:0)
最后,我决定在ColorExtractor.cs中创建一个事件:
public static event EventHandler Analysed;
public async static void Analyse(BitmapImage poster)
{
//Analyse colors
Analysed(null, null);
}
然后,在我的MainPage.xaml.cs上:
ColorExtractor.Analyse(bmp);
ColorExtractor.Analysed += (sender, EventArgs) =>
{
//Set Page foreground color, as a lot of controls are dynamically binded to their parent's foreground brush.
//If a control isn't automatically binded, all I have to do is say: Foreground="{Binding Foreground, ElementName=page}"
page.Foreground = Application.Current.Resources["SystemControlForegroundAccentBrush"] as SolidColorBrush;
page.BorderBrush = Application.Current.Resources["SystemControlHighlightAccentBrush"] as SolidColorBrush;
//Reload any custom user control that sets it's children's color when it's loaded.
backdrop.UserControl_Loaded(null, null);
};
所以我实际上并没有直接将我的控件绑定到ForegroundAccentBrush,但这样做无需重新导航到该页面。