UWP RequestedTheme 在 ListView 和 ListViewItem 中不一致
UWP RequestedTheme is not consistent in ListView and ListViewItem
我的NowPlayFullPage has a PlaylistControl,基本上就是一个ListView。
<local:PlaylistControl
x:Name="FullPlaylistControl"
Margin="10,10,10,0"
AllowReorder="True"
AlternatingRowColor="False"
Background="Transparent"
IsNowPlaying="True"
RequestedTheme="Dark" />
PlaylistControl
的ItemTemplate
如下:
<local:PlaylistControlItem
Data="{x:Bind}"
DataContext="{x:Bind}"
RequestedTheme="{Binding ElementName=PlaylistController, Path=RequestedTheme}"
ShowAlbumText="{Binding ElementName=PlaylistController, Path=ShowAlbumText}" />
并且在 PlaylistControlItem
的 Loaded
事件中,我调用了一个函数 SetTextColor
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
MediaHelper.SwitchMusicListeners.Add(this);
SetTextColor(MediaHelper.CurrentMusic);
}
public void SetTextColor(Music music)
{
if (Data == music)
{
TitleTextBlock.Foreground = ArtistTextButton.Foreground = AlbumTextButton.Foreground = DurationTextBlock.Foreground =
LongArtistTextButton.Foreground = LongArtistAlbumPanelDot.Foreground = LongAlbumTextButton.Foreground = ColorHelper.HighlightBrush;
TextColorChanged = true;
}
else if (TextColorChanged)
{
if (RequestedTheme == ElementTheme.Dark)
{
TitleTextBlock.Foreground = ColorHelper.WhiteBrush;
ArtistTextButton.Foreground = AlbumTextButton.Foreground = DurationTextBlock.Foreground =
LongArtistTextButton.Foreground = LongArtistAlbumPanelDot.Foreground = LongAlbumTextButton.Foreground = ColorHelper.GrayBrush;
}
else
{
TitleTextBlock.Foreground = ArtistTextButton.Foreground = AlbumTextButton.Foreground = DurationTextBlock.Foreground =
LongArtistTextButton.Foreground = LongArtistAlbumPanelDot.Foreground = LongAlbumTextButton.Foreground = ColorHelper.BlackBrush;
}
TextColorChanged = false;
}
}
我的问题是,为什么在Loaded
事件中调用的SetTextColor
中的RequestedTheme
的值是ElementTheme.Default
而不是ElementTheme.Dark
? PlaylistControlItem
的 RequestTheme
什么时候保持 Dark
的值,以便我的文本颜色可以正确设置?
建议您在 XAML 中使用 ThemeResource 来处理这个问题,而不是在代码中,请参阅:https://docs.microsoft.com/en-us/windows/uwp/xaml-platform/themeresource-markup-extension
但要回答您的问题,这是预期的行为。 ElementTheme.Default
仅表示该元素尚未覆盖其主题,并且正在使用默认的应用主题。其他两个值表示该元素已明确覆盖其主题。 App.Current.RequestedTheme
给出应用程序的 实际 主题。 FrameworkElement.RequestedTheme
将始终具有 Default
的值,除非您在该特定元素上明确将其设置为其他值。所有 children 的值仍为 Default
.
请注意,您应该与 ActualTheme
进行比较,而不是 RequestedTheme
,因为 parent 可能导致它使用与应用程序不同的主题,如果它的值仍然是 ElementTheme.Default
.
下面的方法可能会帮助您获得 Light/Dark 的正确值。
public static ElementTheme GetEffectiveTheme(FrameworkElement e)
{
if (e.ActualTheme == ElementTheme.Default)
return App.Current.RequestedTheme == ApplicationTheme.Dark ? ElementTheme.Dark : ElementTheme.Light;
return e.ActualTheme;
}
而且,只需使用 ThemeResources。它们会自动 re-evaluate 更改主题,无需任何代码或事件侦听器。
我的NowPlayFullPage has a PlaylistControl,基本上就是一个ListView。
<local:PlaylistControl
x:Name="FullPlaylistControl"
Margin="10,10,10,0"
AllowReorder="True"
AlternatingRowColor="False"
Background="Transparent"
IsNowPlaying="True"
RequestedTheme="Dark" />
PlaylistControl
的ItemTemplate
如下:
<local:PlaylistControlItem
Data="{x:Bind}"
DataContext="{x:Bind}"
RequestedTheme="{Binding ElementName=PlaylistController, Path=RequestedTheme}"
ShowAlbumText="{Binding ElementName=PlaylistController, Path=ShowAlbumText}" />
并且在 PlaylistControlItem
的 Loaded
事件中,我调用了一个函数 SetTextColor
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
MediaHelper.SwitchMusicListeners.Add(this);
SetTextColor(MediaHelper.CurrentMusic);
}
public void SetTextColor(Music music)
{
if (Data == music)
{
TitleTextBlock.Foreground = ArtistTextButton.Foreground = AlbumTextButton.Foreground = DurationTextBlock.Foreground =
LongArtistTextButton.Foreground = LongArtistAlbumPanelDot.Foreground = LongAlbumTextButton.Foreground = ColorHelper.HighlightBrush;
TextColorChanged = true;
}
else if (TextColorChanged)
{
if (RequestedTheme == ElementTheme.Dark)
{
TitleTextBlock.Foreground = ColorHelper.WhiteBrush;
ArtistTextButton.Foreground = AlbumTextButton.Foreground = DurationTextBlock.Foreground =
LongArtistTextButton.Foreground = LongArtistAlbumPanelDot.Foreground = LongAlbumTextButton.Foreground = ColorHelper.GrayBrush;
}
else
{
TitleTextBlock.Foreground = ArtistTextButton.Foreground = AlbumTextButton.Foreground = DurationTextBlock.Foreground =
LongArtistTextButton.Foreground = LongArtistAlbumPanelDot.Foreground = LongAlbumTextButton.Foreground = ColorHelper.BlackBrush;
}
TextColorChanged = false;
}
}
我的问题是,为什么在Loaded
事件中调用的SetTextColor
中的RequestedTheme
的值是ElementTheme.Default
而不是ElementTheme.Dark
? PlaylistControlItem
的 RequestTheme
什么时候保持 Dark
的值,以便我的文本颜色可以正确设置?
建议您在 XAML 中使用 ThemeResource 来处理这个问题,而不是在代码中,请参阅:https://docs.microsoft.com/en-us/windows/uwp/xaml-platform/themeresource-markup-extension
但要回答您的问题,这是预期的行为。 ElementTheme.Default
仅表示该元素尚未覆盖其主题,并且正在使用默认的应用主题。其他两个值表示该元素已明确覆盖其主题。 App.Current.RequestedTheme
给出应用程序的 实际 主题。 FrameworkElement.RequestedTheme
将始终具有 Default
的值,除非您在该特定元素上明确将其设置为其他值。所有 children 的值仍为 Default
.
请注意,您应该与 ActualTheme
进行比较,而不是 RequestedTheme
,因为 parent 可能导致它使用与应用程序不同的主题,如果它的值仍然是 ElementTheme.Default
.
下面的方法可能会帮助您获得 Light/Dark 的正确值。
public static ElementTheme GetEffectiveTheme(FrameworkElement e)
{
if (e.ActualTheme == ElementTheme.Default)
return App.Current.RequestedTheme == ApplicationTheme.Dark ? ElementTheme.Dark : ElementTheme.Light;
return e.ActualTheme;
}
而且,只需使用 ThemeResources。它们会自动 re-evaluate 更改主题,无需任何代码或事件侦听器。