Hi Alex, Actually, this bug is reported to me by a Flex Developer, who is a friend of mine.
The demand is, he wants to set a default skin class for his component (which extends SkinnableComponent), so inside the constructor of his component, he writes this: setStyle("skinClass", MyDefaultSkin); super(); Then, he wants other people to apply a different skin if they want to, other people would write this: <ns:MyComponent styleName="otherSkin"/> I think his demand is very common, now the problem is, by doing so, the skin won't change. This bug only affects on custom SkinnableComponent, but it doesn't affect on any built in Flex Components like Spark Button, CheckBox, etc.. That's why I think it is a bug : ) DarkStone 2014-12-18 At 2014-12-18 01:30:23, "Alex Harui" <aha...@adobe.com> wrote: >Hi Darkstone, > >By this description, this is not a bug. Any style set via setStyle >overrides styles in CSS selectors. The more common case is someone does >want to always have myComponent use SkinA regardless of underlying changes >to the selectors, like when style modules are loaded. If you want an >overridden style to revert to using the styles of the selectors, then you >have to call clearStyle in your code. > >-Alex > > >On 12/17/14, 2:05 AM, "DarkStone" <darkst...@163.com> wrote: > >>Hi Alex, >> >>I've located the problem: >> >>Step 1. Using MySkinnableComponent.setStyle("skinClass", SkinA) to apply >>an initial skin is ok. >> >>Step 2. Then using MySkinnableComponent.styleName = "skinB" won't work, >>the skin won't change. >> >>When [Step 2] happens, inside the validateSkinChange() function of >>SkinnableComponent.as (line 440-443): >> >>newSkinClass = getStyle("skinClass"); >>skipReload = newSkinClass && getQualifiedClassName(newSkinClass) == >>getQualifiedClassName(_skin); >> >>The getStyle("skinClass") returns the old skin (SkinA), which should be >>the new skin (SkinB). >> >>As a result, the newSkinClass && getQualifiedClassName(newSkinClass) == >>getQualifiedClassName(_skin) returns true, which should be false. >> >>That's why the SkinnableComponent won't change the skin. >> >> >> >>I know how to fix this now. >> >>No need to override the styleName setter function in >>SkinnableComponent.as. >> >>Just add a line clearStyle("skinClass") to styleChanged() function in >>SkinnableComponent.as (add at line 552): >> >>override public function styleChanged(styleProp:String):void >>{ >> var allStyles:Boolean = styleProp == null || styleProp == "styleName"; >> >> if (allStyles || styleProp == "skinClass" || styleProp == >>"skinFactory") >> { >> clearStyle("skinClass"); //This will fix the bug >> skinChanged = true; >> invalidateProperties(); >> >> if (styleProp == "skinFactory") >> skinFactoryStyleChanged = true; >> } >> >> super.styleChanged(styleProp); >>} >> >>clearStyle("skinClass"); //This will fix the bug >>That's the only line needs to be added, in order to fix this bug. >> >> >>I've already updated the JIRA for this >>https://issues.apache.org/jira/browse/FLEX-34689 >> >> >>DarkStone >>2014-12-17 >> >> >>在 2014-12-17 14:12:52,"Alex Harui" <aha...@adobe.com> 写道: >>> >>> >>>On 12/16/14, 9:36 PM, "DarkStone" <darkst...@163.com> wrote: >>> >>>>Hi Alex, >>>> >>>>Why this needs to be fixed is simple: >>>> >>>>1. Using MySkinnableComponent.setStyle("skinClass", SkinA) to apply an >>>>initial skin is ok. >>>> >>>>2. Then using MySkinnableComponent.styleName = "skinB" won't work, the >>>>skin won't change. >>>> >>>>The styleChanged() function in SkinnableComponent doesn't handle this >>>>scenario correctly, that's why we need to override the styleName setter >>>>function to fix this. >>> >>>I’m wondering why the styleChanged() function can’t be changed to handle >>>this scenario correctly. There are other ways to change skinClass, like >>>setting it directly in a CSSStyleDeclaration or by loading a Style >>>module. >>> I would expect them all to call styleChanged() and the right thing to >>>happen. >>> >>>Thanks, >>>-Alex >>> >