2013-11-26 8 views
0

我有一个包含按钮样式的资源字典。在按钮的控制模板中,我有4个边框,每个边框代表特定的视觉状态 - 正常,悬停,点击和禁用。 4个故事板对象(每个状态一个)将相应边框的可见性翻转为可见,并将其余边框折叠。这产生了从一个状态到下一个状态平滑过渡的效果。当声明为静态资源并在控制临时文件中使用时,在运行时更改LinearGradientBrush的GradientStops

每个边框代表一个给定的状态,边框厚度为2px,圆角为10px。边框画笔被引用为BorderBrush="{StaticResource BorderBrushName}",而边框的背景也以类似的方式声明:Background="{StaticResource BackgroundBrushName}"

这个作品非常棒,但我已经被授权做一些调色板切换。由于我们做了很多明确的样式,并且该应用程序是Silverlight 5应用程序,所以当显式样式引用启动时应用程序爆炸时,我无法真正实现主题......但这是另一个讨论。

所以我的问题是,“重新主题”应用程序的唯一方法是翻转每个画笔的颜色,并改变每个图像的URI,因为大量使用显式样式。

虽然能够在其他控件中这样做,但无论我试图改变按钮的外观 - 它完全没有价值,我不知道为什么。

我在做什么错了?当我隔离代码并将其放入它自己的应用程序时,一切正常。在有问题的实际应用程序内...所有其他元素都会更改其颜色/图像,接受有问题的按钮。

的代码波纹管附: [Theme/Pallete Switching Code]

public static class ThemeManager 
    { 
    /// <summary> 
    /// Does things. 
    /// </summary> 
    /// <param name="newTheme"></param> 
    public static void ChangeTheme(PiranhaTheme newTheme) 
    { 
     Uri defaultUri = new Uri("/MyApp;component/Themes/Blue/Blue.xaml", UriKind.Relative); 
     Uri themeUri = null; 

     if (newTheme == PiranhaTheme.Blue) 
     { 
     themeUri = new Uri("/MyApp;component/Themes/Blue/Blue.xaml", UriKind.Relative); 
     } 
     else if (newTheme == PiranhaTheme.Dark) 
     { 
     themeUri = new Uri("/MyApp;component/Themes/Dark/Dark.xaml", UriKind.Relative); 
     } 
     else 
     { 
     themeUri = new Uri("/MyApp;component/Themes/Light/LightTheme.xaml", UriKind.Relative); 
     } 

     ResourceDictionary defaultDictionary = ThemeManager.GetResourceDictionary(defaultUri); 
     ResourceDictionary themeDictionary = ThemeManager.GetResourceDictionary(themeUri); 

     foreach (var key in defaultDictionary.Keys) 
     { 
     var currentValue = App.Current.Resources[key]; 
     var newValue = themeDictionary[key]; 

     if (newValue != null && currentValue != null) 
     { 
      if(newValue is SolidColorBrush && currentValue is SolidColorBrush) 
      { 
      var newSolidBrush = (SolidColorBrush)newValue; 
      var currentSolidBrush = (SolidColorBrush)currentValue; 

      currentSolidBrush.Color = newSolidBrush.Color; 
      } 
      else if (newValue is LinearGradientBrush && currentValue is LinearGradientBrush) 
      { 
      var newGradientBrush = (LinearGradientBrush)newValue; 
      var currentGradientBrush = (LinearGradientBrush)currentValue; 

      currentGradientBrush.GradientStops.Clear(); 

      for (int i = 0; i < newGradientBrush.GradientStops.Count; i++) 
      { 
       GradientStop gradientStop = newGradientBrush.GradientStops[i]; 

       GradientStop newGradientStop = new GradientStop(); 
       newGradientStop.Color = gradientStop.Color; 
       newGradientStop.Offset = gradientStop.Offset; 

       currentGradientBrush.GradientStops.Add(newGradientStop); 
      } 

      } 
      else if (newValue is BitmapImage && currentValue is BitmapImage) 
      { 
      var newBitmapImage = (BitmapImage)newValue; 
      var currentBitmapImage = (BitmapImage)currentValue; 

      currentBitmapImage.UriSource = newBitmapImage.UriSource; 
      } 
      else if (newValue is Image && currentValue is Image) 
      { 
      var newImage = (Image)newValue; 
      var curImage = (Image)currentValue; 

      curImage.Source = newImage.Source; 
      } 
     } 
     } 
    } 

    private static ResourceDictionary GetResourceDictionary(Uri dictionaryUri) 
    { 
     ResourceDictionary result = new ResourceDictionary(); 

     try 
     { 
     Application.LoadComponent(result, dictionaryUri); 
     } 
     catch { } 

     return result; 
    } 
    } 

[App.xaml]

<Application.Resources> 
    <ResourceDictionary> 
     <ResourceDictionary.MergedDictionaries> 
      <ResourceDictionary Source="/MyApp;component/Assets/BlueTheme.xaml"/> 
      <ResourceDictionary Source="/MyApp;component/Assets/ButtonStyles.xaml"/> 
     </ResourceDictionary.MergedDictionaries> 
    </ResourceDictionary> 
</Application.Resources> 

[Button Style - On It's Own Resource Dictionary]

<ResourceDictionary 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> 
    <Style x:Key="MainLaunchMenuButtonStyle" TargetType="Button"> 
     <Setter Property="Background" Value="Transparent"/> 
     <Setter Property="Foreground" Value="White"/> 
     <Setter Property="Padding" Value="3"/> 
     <Setter Property="BorderThickness" Value="1"/> 
     <Setter Property="BorderBrush" Value="Transparent"/> 
     <Setter Property="Template"> 
      <Setter.Value> 
       <ControlTemplate TargetType="Button"> 
        <Grid> 
         <VisualStateManager.VisualStateGroups> 
          <VisualStateGroup x:Name="CommonStates"> 
           <VisualState x:Name="Normal"> 
            <Storyboard> 
             <ObjectAnimationUsingKeyFrames Storyboard.TargetName="RegularState" Storyboard.TargetProperty="Visibility" > 
              <DiscreteObjectKeyFrame KeyTime="0:0:0"> 
               <DiscreteObjectKeyFrame.Value> 
               <Visibility>Visible</Visibility> 
               </DiscreteObjectKeyFrame.Value> 
              </DiscreteObjectKeyFrame> 
             </ObjectAnimationUsingKeyFrames> 
             <ObjectAnimationUsingKeyFrames Storyboard.TargetName="HoverState" Storyboard.TargetProperty="Visibility" > 
              <DiscreteObjectKeyFrame KeyTime="0:0:0"> 
               <DiscreteObjectKeyFrame.Value> 
               <Visibility>Collapsed</Visibility> 
               </DiscreteObjectKeyFrame.Value> 
              </DiscreteObjectKeyFrame> 
             </ObjectAnimationUsingKeyFrames> 
             <ObjectAnimationUsingKeyFrames Storyboard.TargetName="MousePressedState" Storyboard.TargetProperty="Visibility" > 
              <DiscreteObjectKeyFrame KeyTime="0:0:0"> 
               <DiscreteObjectKeyFrame.Value> 
               <Visibility>Collapsed</Visibility> 
               </DiscreteObjectKeyFrame.Value> 
              </DiscreteObjectKeyFrame> 
             </ObjectAnimationUsingKeyFrames> 
             <ObjectAnimationUsingKeyFrames Storyboard.TargetName="DisabledState" Storyboard.TargetProperty="Visibility" > 
              <DiscreteObjectKeyFrame KeyTime="0:0:0"> 
               <DiscreteObjectKeyFrame.Value> 
               <Visibility>Collapsed</Visibility> 
               </DiscreteObjectKeyFrame.Value> 
              </DiscreteObjectKeyFrame> 
             </ObjectAnimationUsingKeyFrames> 
            </Storyboard> 
           </VisualState> 
           <VisualState x:Name="MouseOver"> 
            <Storyboard> 
             <ObjectAnimationUsingKeyFrames Storyboard.TargetName="RegularState" Storyboard.TargetProperty="Visibility" > 
              <DiscreteObjectKeyFrame KeyTime="0:0:0"> 
               <DiscreteObjectKeyFrame.Value> 
               <Visibility>Collapsed</Visibility> 
               </DiscreteObjectKeyFrame.Value> 
              </DiscreteObjectKeyFrame> 
             </ObjectAnimationUsingKeyFrames> 
             <ObjectAnimationUsingKeyFrames Storyboard.TargetName="HoverState" Storyboard.TargetProperty="Visibility" > 
              <DiscreteObjectKeyFrame KeyTime="0:0:0"> 
               <DiscreteObjectKeyFrame.Value> 
               <Visibility>Visible</Visibility> 
               </DiscreteObjectKeyFrame.Value> 
              </DiscreteObjectKeyFrame> 
             </ObjectAnimationUsingKeyFrames> 
             <ObjectAnimationUsingKeyFrames Storyboard.TargetName="MousePressedState" Storyboard.TargetProperty="Visibility" > 
              <DiscreteObjectKeyFrame KeyTime="0:0:0"> 
               <DiscreteObjectKeyFrame.Value> 
               <Visibility>Collapsed</Visibility> 
               </DiscreteObjectKeyFrame.Value> 
              </DiscreteObjectKeyFrame> 
             </ObjectAnimationUsingKeyFrames> 
             <ObjectAnimationUsingKeyFrames Storyboard.TargetName="DisabledState" Storyboard.TargetProperty="Visibility" > 
              <DiscreteObjectKeyFrame KeyTime="0:0:0"> 
               <DiscreteObjectKeyFrame.Value> 
               <Visibility>Collapsed</Visibility> 
               </DiscreteObjectKeyFrame.Value> 
              </DiscreteObjectKeyFrame> 
             </ObjectAnimationUsingKeyFrames> 
            </Storyboard> 
           </VisualState> 
           <VisualState x:Name="Pressed"> 
            <Storyboard> 
             <ObjectAnimationUsingKeyFrames Storyboard.TargetName="RegularState" Storyboard.TargetProperty="Visibility" > 
              <DiscreteObjectKeyFrame KeyTime="0:0:0"> 
               <DiscreteObjectKeyFrame.Value> 
               <Visibility>Collapsed</Visibility> 
               </DiscreteObjectKeyFrame.Value> 
              </DiscreteObjectKeyFrame> 
             </ObjectAnimationUsingKeyFrames> 
             <ObjectAnimationUsingKeyFrames Storyboard.TargetName="HoverState" Storyboard.TargetProperty="Visibility" > 
              <DiscreteObjectKeyFrame KeyTime="0:0:0"> 
               <DiscreteObjectKeyFrame.Value> 
               <Visibility>Collapsed</Visibility> 
               </DiscreteObjectKeyFrame.Value> 
              </DiscreteObjectKeyFrame> 
             </ObjectAnimationUsingKeyFrames> 
             <ObjectAnimationUsingKeyFrames Storyboard.TargetName="MousePressedState" Storyboard.TargetProperty="Visibility" > 
              <DiscreteObjectKeyFrame KeyTime="0:0:0"> 
               <DiscreteObjectKeyFrame.Value> 
               <Visibility>Visible</Visibility> 
               </DiscreteObjectKeyFrame.Value> 
              </DiscreteObjectKeyFrame> 
             </ObjectAnimationUsingKeyFrames> 
             <ObjectAnimationUsingKeyFrames Storyboard.TargetName="DisabledState" Storyboard.TargetProperty="Visibility" > 
              <DiscreteObjectKeyFrame KeyTime="0:0:0"> 
               <DiscreteObjectKeyFrame.Value> 
               <Visibility>Collapsed</Visibility> 
               </DiscreteObjectKeyFrame.Value> 
              </DiscreteObjectKeyFrame> 
             </ObjectAnimationUsingKeyFrames> 
            </Storyboard> 
           </VisualState> 
           <VisualState x:Name="Disabled"> 
            <Storyboard> 
             <ObjectAnimationUsingKeyFrames Storyboard.TargetName="RegularState" Storyboard.TargetProperty="Visibility" > 
              <DiscreteObjectKeyFrame KeyTime="0:0:0"> 
               <DiscreteObjectKeyFrame.Value> 
               <Visibility>Collapsed</Visibility> 
               </DiscreteObjectKeyFrame.Value> 
              </DiscreteObjectKeyFrame> 
             </ObjectAnimationUsingKeyFrames> 
             <ObjectAnimationUsingKeyFrames Storyboard.TargetName="HoverState" Storyboard.TargetProperty="Visibility" > 
              <DiscreteObjectKeyFrame KeyTime="0:0:0"> 
               <DiscreteObjectKeyFrame.Value> 
               <Visibility>Collapsed</Visibility> 
               </DiscreteObjectKeyFrame.Value> 
              </DiscreteObjectKeyFrame> 
             </ObjectAnimationUsingKeyFrames> 
             <ObjectAnimationUsingKeyFrames Storyboard.TargetName="MousePressedState" Storyboard.TargetProperty="Visibility" > 
              <DiscreteObjectKeyFrame KeyTime="0:0:0"> 
               <DiscreteObjectKeyFrame.Value> 
               <Visibility>Collapsed</Visibility> 
               </DiscreteObjectKeyFrame.Value> 
              </DiscreteObjectKeyFrame> 
             </ObjectAnimationUsingKeyFrames> 
             <ObjectAnimationUsingKeyFrames Storyboard.TargetName="DisabledState" Storyboard.TargetProperty="Visibility" > 
              <DiscreteObjectKeyFrame KeyTime="0:0:0"> 
               <DiscreteObjectKeyFrame.Value> 
               <Visibility>Visible</Visibility> 
               </DiscreteObjectKeyFrame.Value> 
              </DiscreteObjectKeyFrame> 
             </ObjectAnimationUsingKeyFrames> 
            </Storyboard> 
           </VisualState> 
          </VisualStateGroup> 
          <VisualStateGroup x:Name="FocusStates"> 
           <VisualState x:Name="Focused"/> 
           <VisualState x:Name="Unfocused"/> 
          </VisualStateGroup> 
         </VisualStateManager.VisualStateGroups> 
         <Border x:Name="RegularState" Visibility="Visible" BorderBrush="{StaticResource MainLaunchMenuButtonRegularStateBorderBrush}" Background="{StaticResource MainLaunchMenuButtonHoverStateBackgroundBrush}" BorderThickness="2" CornerRadius="10" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/> 
         <Border x:Name="HoverState" Visibility="Collapsed" BorderBrush="{StaticResource MainLaunchMenuButtonHoverStateBorderBrush}" Background="{StaticResource MainLaunchMenuButtonHoverStateBackgroundBrush}" BorderThickness="2" CornerRadius="10" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/> 
         <Border x:Name="MousePressedState" Visibility="Collapsed" BorderBrush="{StaticResource MainLaunchMenuButtonPressedStateBorderBrush}" Background="{StaticResource MainLaunchMenuButtonPressedStateBackgroundBrush}" BorderThickness="2" CornerRadius="10" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" /> 
         <Border x:Name="DisabledState" Visibility="Collapsed" BorderBrush="{StaticResource MainLaunchMenuButtonDisabledStateBorderBrush}" Background="{StaticResource MainLaunchMenuButtonDisabledStateBackgroundBrush}" BorderThickness="2" CornerRadius="10" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" /> 
         <ContentPresenter x:Name="contentPresenter" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/> 
        </Grid> 
       </ControlTemplate> 
      </Setter.Value> 
     </Setter> 
    </Style> 
</ResourceDictionary> 

[Blue Theme]

<ResourceDictionary 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> 
    <SolidColorBrush x:Key="MainWindowBackground" Color="#FF003A6D" /> 
    <SolidColorBrush x:Key="MainLaunchMenuButtonRegularStateBorderBrush" Color="#78A4D4"/> 
    <LinearGradientBrush x:Key="MainLaunchMenuButtonRegularStateBackgroundBrush" EndPoint="0.5,1" StartPoint="0.5,0"> 
     <GradientStop Color="#FF002141" Offset="1"/> 
     <GradientStop Color="#FF1C4973"/> 
     <GradientStop Color="#FF002141" Offset="0.6"/> 
    </LinearGradientBrush> 
    <SolidColorBrush x:Key="MainLaunchMenuButtonHoverStateBorderBrush" Color="#FFFF8500"/> 
    <LinearGradientBrush x:Key="MainLaunchMenuButtonHoverStateBackgroundBrush" EndPoint="0.5,1" StartPoint="0.5,0"> 
     <GradientStop Color="#FF002141" Offset="1"/> 
     <GradientStop Color="#FF1C4973"/> 
     <GradientStop Color="#FF002141" Offset="0.6"/> 
    </LinearGradientBrush> 
    <SolidColorBrush x:Key="MainLaunchMenuButtonPressedStateBorderBrush" Color="#002141"/> 
    <LinearGradientBrush x:Key="MainLaunchMenuButtonPressedStateBackgroundBrush" EndPoint="0.5,1" StartPoint="0.5,0"> 
     <GradientStop Color="#FFFF8500" Offset="0.6"/> 
     <GradientStop Color="#FFFF8500" Offset="1"/> 
     <GradientStop Color="#FFFF9B43"/> 
    </LinearGradientBrush> 
    <SolidColorBrush x:Key="MainLaunchMenuButtonDisabledStateBorderBrush" Color="#8078A4D4"/> 
    <LinearGradientBrush x:Key="MainLaunchMenuButtonDisabledStateBackgroundBrush" EndPoint="0.5,1" StartPoint="0.5,0"> 
     <GradientStop Color="#80123C62" Offset="0.6"/> 
     <GradientStop Color="#80002141" Offset="1"/> 
     <GradientStop Color="#801C4973"/> 
    </LinearGradientBrush> 

</ResourceDictionary> 

[Light Theme]

<ResourceDictionary 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> 
    <SolidColorBrush x:Key="MainWindowBackground" Color="#333333" /> 
    <SolidColorBrush x:Key="MainLaunchMenuButtonRegularStateBorderBrush" Color="#2F2F2F"/> 
    <LinearGradientBrush x:Key="MainLaunchMenuButtonRegularStateBackgroundBrush" EndPoint="0.5,1" StartPoint="0.5,0"> 
    <GradientStop Color="#FF404040"/> 
    <GradientStop Color="#FF4E4E4E" Offset="0.6"/> 
    <GradientStop Color="#FF535353" Offset="1"/> 
    </LinearGradientBrush> 
    <SolidColorBrush x:Key="MainLaunchMenuButtonHoverStateBorderBrush" Color="#28728B"/> 
    <LinearGradientBrush x:Key="MainLaunchMenuButtonHoverStateBackgroundBrush" EndPoint="0.5,1" StartPoint="0.5,0"> 
    <GradientStop Color="#FF46C8F6"/> 
    <GradientStop Color="#FF42C4F2" Offset="0.6"/> 
    <GradientStop Color="#FF34ADD8" Offset="1"/> 
    </LinearGradientBrush> 
    <SolidColorBrush x:Key="MainLaunchMenuButtonPressedStateBorderBrush" Color="#2F2F2F"/> 
    <LinearGradientBrush x:Key="MainLaunchMenuButtonPressedStateBackgroundBrush" EndPoint="0.5,1" StartPoint="0.5,0"> 
    <GradientStop Color="#FF46C8F6"/> 
    <GradientStop Color="#FF42C4F2" Offset="0.6"/> 
    <GradientStop Color="#FF34ADD8" Offset="1"/> 
    </LinearGradientBrush> 
    <SolidColorBrush x:Key="MainLaunchMenuButtonDisabledStateBorderBrush" Color="#802F2F2F"/> 
    <LinearGradientBrush x:Key="MainLaunchMenuButtonDisabledStateBackgroundBrush" EndPoint="0.5,1" StartPoint="0.5,0"> 
    <GradientStop Color="#804D4D4D" Offset="0.6"/> 
    <GradientStop Color="#80505050" Offset="1"/> 
    <GradientStop Color="#80404040"/> 
    </LinearGradientBrush> 
</ResourceDictionary> 

回答

0

好了,我找到了解决这个有趣的问题。问题是,尽管App.Current.Resources["Key"]将检索特定资源,但这并不意味着它是该资源的唯一实例。

因此,如果一个ResourceDictionary通过MergedDictionaries属性引用另一个,该属性可有效创建任何被引用的新实例。因此,如果我们有App.xaml,资源字典A和B以及A中的样式是在B中声明的引用键,那么实际上我们可以有两个B实例 - 当我们在app.xaml中声明引用时,另一个实例一个在A中。

所以,如果我们想要改变在B中声明的画笔的颜色,那么我们必须递归地(找到那个画笔的每个实例)。我们会通过查看每个字典并合并字典集合以及合并字典的合并字典来实现此目的....并且每当其键(当前字典内)存在时更改画笔的颜色代码,并且在该键下声明的资源具有相同的类型。

相关问题