我目前正在开发一个WPF应用程序,允许用户在运行时更改其主题(无需重启)。我目前正在使用此处的代码:
http://svetoslavsavov.blogspot.de/2009/07/switching-wpf-interface-themes-at.html
我用Try
语句对其进行了修改:
private static void ApplyTheme(FrameworkElement targetElement, Uri dictionaryUri)
{
if (targetElement == null) return;
try
{
ResourceDictionary themeDictionary = null;
if (dictionaryUri != null)
{
themeDictionary = new ResourceDictionary();
themeDictionary.Source = dictionaryUri;
targetElement.Resources.MergedDictionaries.Insert(0, themeDictionary);
}
List<ResourceDictionary> existingDictionaries =
(from dictionary in targetElement.Resources.MergedDictionaries.OfType<ResourceDictionary>()
select dictionary).ToList();
foreach (ResourceDictionary thDictionary in existingDictionaries)
{
if (themeDictionary == thDictionary) continue;
try
{
targetElement.Resources.MergedDictionaries.Remove(thDictionary);
}
catch { }
}
}
finally { }
}
但如果我在我的应用程序中设置了ScrollBars样式,它就不会起作用。它第一次总是将相同的ComboBox变成一个矩形,你不能再使用它了:
第二次抛出异常:
Unable to cast object of type 'MS.Internal.NamedObject' to type 'System.Windows.FrameworkTemplate'.
如果我删除Try
语句,它会在第一次抛出异常。
ScrollBar样式如下所示:
<!-- Colors -->
<Color x:Key="Accent">#FFFEB809</Color>
<SolidColorBrush x:Key="AccentBrush" Color="{StaticResource Accent}"/>
<Color x:Key="AccentConsole">#22FEB809</Color>
<SolidColorBrush x:Key="AccentConsoleBrush" Color="{StaticResource AccentConsole}"/>
<Color x:Key="AccentLight">#FFFFDB82</Color>
<SolidColorBrush x:Key="AccentLightBrush" Color="{StaticResource AccentLight}"/>
<Color x:Key="AccentLightConsole">#22FFDB82</Color>
<SolidColorBrush x:Key="AccentLightConsoleBrush" Color="{StaticResource AccentLightConsole}"/>
<Color x:Key="AccentText">#FFFFFFFF</Color>
<SolidColorBrush x:Key="AccentTextBrush" Color="{StaticResource AccentText}"/>
<Color x:Key="Border">#FFCCCCCC</Color>
<SolidColorBrush x:Key="BorderBrush" Color="{StaticResource Border}"/>
<Color x:Key="CaptionBar">#FFFCFCFC</Color>
<SolidColorBrush x:Key="CaptionBarBrush" Color="{StaticResource CaptionBar}"/>
<Color x:Key="ConsoleBackground">#FF222222</Color>
<SolidColorBrush x:Key="ConsoleBackgroundBrush" Color="{StaticResource ConsoleBackground}"/>
<Color x:Key="ControlBackground">White</Color>
<SolidColorBrush x:Key="ControlBackgroundBrush" Color="{StaticResource ControlBackground}"/>
<Color x:Key="NavigationHeader">#88000000</Color>
<SolidColorBrush x:Key="NavigationHeaderBrush" Color="{StaticResource NavigationHeader}"/>
<Color x:Key="Window">#FFFAFAFA</Color>
<SolidColorBrush x:Key="WindowBrush" Color="{StaticResource Window}"/>
<Style x:Key="{x:Type ScrollBar}" TargetType="{x:Type ScrollBar}">
<Setter Property="SnapsToDevicePixels" Value="True"/>
<Setter Property="OverridesDefaultStyle" Value="True"/>
<Setter Property="Margin" Value="2"/>
<Style.Triggers>
<Trigger Property="Orientation" Value="Horizontal">
<Setter Property="Template" Value="{StaticResource HorizontalScrollBar}"/>
<Setter Property="Height" Value="24"/>
</Trigger>
<Trigger Property="Orientation" Value="Vertical">
<Setter Property="Template" Value="{StaticResource VerticalScrollBar}"/>
<Setter Property="Width" Value="24"/>
</Trigger>
</Style.Triggers>
</Style>
<ControlTemplate x:Key="HorizontalScrollBar" TargetType="{x:Type ScrollBar}">
<Grid>
<Border Background="#22000000" CornerRadius="4">
<Track Name="PART_Track">
<Track.DecreaseRepeatButton>
<RepeatButton Style="{StaticResource ScrollBarPageButton}" Command="ScrollBar.PageLeftCommand"/>
</Track.DecreaseRepeatButton>
<Track.Thumb>
<!-- The problem occurs here -->
<Thumb Style="{StaticResource HorizontalScrollBarThumb}"/>
</Track.Thumb>
<Track.IncreaseRepeatButton>
<RepeatButton Style="{StaticResource ScrollBarPageButton}" Command="ScrollBar.PageRightCommand"/>
</Track.IncreaseRepeatButton>
</Track>
</Border>
</Grid>
</ControlTemplate>
<ControlTemplate x:Key="VerticalScrollBar" TargetType="{x:Type ScrollBar}">
<Grid>
<Border Background="#22000000" CornerRadius="4">
<Track Name="PART_Track" IsDirectionReversed="True">
<Track.DecreaseRepeatButton>
<RepeatButton Style="{StaticResource ScrollBarPageButton}" Command="ScrollBar.PageUpCommand"/>
</Track.DecreaseRepeatButton>
<Track.Thumb>
<!-- The problem occurs here -->
<Thumb Style="{StaticResource VerticalScrollBarThumb}"/>
</Track.Thumb>
<Track.IncreaseRepeatButton>
<RepeatButton Style="{StaticResource ScrollBarPageButton}" Command="ScrollBar.PageDownCommand"/>
</Track.IncreaseRepeatButton>
</Track>
</Border>
</Grid>
</ControlTemplate>
<Style x:Key="HorizontalScrollBarThumb" TargetType="{x:Type Thumb}">
<Setter Property="SnapsToDevicePixels" Value="True"/>
<Setter Property="Foreground" Value="#FF585858"/>
<Setter Property="FontFamily" Value="Segoe UI Semibold"/>
<Setter Property="FontSize" Value="14"/>
<Setter Property="Padding" Value="8"/>
<Setter Property="Focusable" Value="False"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Thumb}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="24"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="24"/>
</Grid.ColumnDefinitions>
<RepeatButton Style="{StaticResource LeftScrollBarLineButton}" Command="ScrollBar.LineLeftCommand"/>
<Border Name="Base" Background="{StaticResource ControlBackgroundBrush}" BorderBrush="{StaticResource BorderBrush}" BorderThickness="0,1,0,1" Grid.Column="1">
<TextBlock Text="" FontFamily="Segoe UI Symbol" Foreground="#FF585858" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
<RepeatButton Style="{StaticResource RightScrollBarLineButton}" Command="ScrollBar.LineRightCommand" Grid.Column="2"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="VerticalScrollBarThumb" TargetType="{x:Type Thumb}">
<Setter Property="SnapsToDevicePixels" Value="True"/>
<Setter Property="Foreground" Value="#FF585858"/>
<Setter Property="FontFamily" Value="Segoe UI Semibold"/>
<Setter Property="FontSize" Value="14"/>
<Setter Property="Padding" Value="8"/>
<Setter Property="Focusable" Value="False"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Thumb}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="24"/>
<RowDefinition Height="*"/>
<RowDefinition Height="24"/>
</Grid.RowDefinitions>
<RepeatButton Style="{StaticResource TopScrollBarLineButton}" Command="ScrollBar.LineUpCommand"/>
<Border Name="Base" Background="{StaticResource ControlBackgroundBrush}" BorderBrush="{StaticResource BorderBrush}" BorderThickness="1,0,1,0" Grid.Row="1">
<TextBlock Text="" FontFamily="Segoe UI Symbol" Foreground="#FF585858" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
<RepeatButton Style="{StaticResource BottomScrollBarLineButton}" Command="ScrollBar.LineDownCommand" Grid.Row="2"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="LeftScrollBarLineButton" TargetType="{x:Type RepeatButton}">
<Setter Property="SnapsToDevicePixels" Value="True"/>
<Setter Property="Foreground" Value="#FF585858"/>
<Setter Property="FontFamily" Value="Segoe UI Symbol"/>
<Setter Property="FontSize" Value="14"/>
<Setter Property="Padding" Value="8"/>
<Setter Property="Focusable" Value="False"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type RepeatButton}">
<Border Name="Base" Background="{StaticResource ControlBackgroundBrush}" BorderBrush="{StaticResource BorderBrush}" CornerRadius="4,0,0,4" BorderThickness="1,1,0,1">
<TextBlock Text="" Foreground="{TemplateBinding Foreground}" FontFamily="{TemplateBinding FontFamily}" FontSize="{TemplateBinding FontSize}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="Base" Property="Background">
<Setter.Value>
<LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1">
<LinearGradientBrush.RelativeTransform>
<RotateTransform Angle="-90"/>
</LinearGradientBrush.RelativeTransform>
<GradientStop Color="{StaticResource AccentLight}" Offset="0"/>
<GradientStop Color="{StaticResource ControlBackground}" Offset="1"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="RightScrollBarLineButton" TargetType="{x:Type RepeatButton}">
<Setter Property="SnapsToDevicePixels" Value="True"/>
<Setter Property="Foreground" Value="#FF585858"/>
<Setter Property="FontFamily" Value="Segoe UI Symbol"/>
<Setter Property="FontSize" Value="14"/>
<Setter Property="Padding" Value="8"/>
<Setter Property="Focusable" Value="False"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type RepeatButton}">
<Border Name="Base" Background="{StaticResource ControlBackgroundBrush}" BorderBrush="{StaticResource BorderBrush}" CornerRadius="0,4,4,0" BorderThickness="0,1,1,1">
<TextBlock Text="" Foreground="{TemplateBinding Foreground}" FontFamily="{TemplateBinding FontFamily}" FontSize="{TemplateBinding FontSize}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="Base" Property="Background">
<Setter.Value>
<LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1">
<LinearGradientBrush.RelativeTransform>
<RotateTransform Angle="90"/>
</LinearGradientBrush.RelativeTransform>
<GradientStop Color="{StaticResource AccentLight}" Offset="0"/>
<GradientStop Color="{StaticResource ControlBackground}" Offset="1"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="TopScrollBarLineButton" TargetType="{x:Type RepeatButton}">
<Setter Property="SnapsToDevicePixels" Value="True"/>
<Setter Property="Foreground" Value="#FF585858"/>
<Setter Property="FontFamily" Value="Segoe UI Symbol"/>
<Setter Property="FontSize" Value="14"/>
<Setter Property="Padding" Value="8"/>
<Setter Property="Focusable" Value="False"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type RepeatButton}">
<Border Name="Base" Background="{StaticResource ControlBackgroundBrush}" BorderBrush="{StaticResource BorderBrush}" CornerRadius="4,4,0,0" BorderThickness="1,1,1,0">
<TextBlock Text="" Foreground="{TemplateBinding Foreground}" FontFamily="{TemplateBinding FontFamily}" FontSize="{TemplateBinding FontSize}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="Base" Property="Background">
<Setter.Value>
<LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1">
<GradientStop Color="{StaticResource AccentLight}" Offset="0"/>
<GradientStop Color="{StaticResource ControlBackground}" Offset="1"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="BottomScrollBarLineButton" TargetType="{x:Type RepeatButton}">
<Setter Property="SnapsToDevicePixels" Value="True"/>
<Setter Property="Foreground" Value="#FF585858"/>
<Setter Property="FontFamily" Value="Segoe UI Symbol"/>
<Setter Property="FontSize" Value="14"/>
<Setter Property="Padding" Value="8"/>
<Setter Property="Focusable" Value="False"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type RepeatButton}">
<Border Name="Base" Background="{StaticResource ControlBackgroundBrush}" BorderBrush="{StaticResource BorderBrush}" CornerRadius="0,0,4,4" BorderThickness="1,0,1,1">
<TextBlock Text="" Foreground="{TemplateBinding Foreground}" FontFamily="{TemplateBinding FontFamily}" FontSize="{TemplateBinding FontSize}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="Base" Property="Background">
<Setter.Value>
<LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1">
<GradientStop Color="{StaticResource AccentLight}" Offset="1"/>
<GradientStop Color="{StaticResource ControlBackground}" Offset="0"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="ScrollBarPageButton" TargetType="{x:Type RepeatButton}">
<Setter Property="SnapsToDevicePixels" Value="True"/>
<Setter Property="Foreground" Value="#FF585858"/>
<Setter Property="FontFamily" Value="Segoe UI Semibold"/>
<Setter Property="FontSize" Value="14"/>
<Setter Property="Padding" Value="8"/>
<Setter Property="Focusable" Value="False"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type RepeatButton}">
<Border/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
但是当我用<Thumb Style="{StaticResource HorizontalScrollBarThumb}"/>
替换<Thumb Style="{StaticResource VerticalScrollBarThumb}"/>
和<Thumb/>
时,它就可以了。
我在Thumb样式中找不到任何可能导致此问题的内容。
感谢您的帮助。
答案 0 :(得分:0)
这是因为模板的顺序。只需更改下图中给出的模板顺序即可。 StaticResources应该在XAML中引用之前进行解析。
上面粘贴的XAML代码也缺少一些画笔资源,如AccentLight,ControlBackgroundBrush。我不知道您的应用程序中是否在适当的层次结构中定义了这些资源。检查一下。