【问题标题】:I want to override the default value of a style inherited from an ancestor component [flex4]我想覆盖从祖先组件继承的样式的默认值 [flex4]
【发布时间】:2026-02-12 04:10:01
【问题描述】:

虽然将 [Style ...] 元数据标记添加到我的子类确实使属性 showPromptWhenFocused 可从 MXML 访问,但 initializeStyles() 函数并未成功地将默认值更改为 true。

如果用户愿意,我希望用户能够将 showPromptWhenFocused 设置为 false,但我希望默认值为 true。

package com.santacruzsoftware.crafting.controls
{
import mx.core.FlexGlobals;
import mx.styles.CSSStyleDeclaration;
import mx.styles.StyleManager;

import spark.components.TextInput;

[Style(name="showPromptWhenFocused", inherit="yes", type="Boolean")]

public class WatermarkTextInput extends TextInput
{
    private static function initializeStyles() : void
    {
        var style : CSSStyleDeclaration = FlexGlobals.topLevelApplication.styleManager.getStyleDeclaration("showPromptWhenFocused");
        if (!style)
            style = new CSSStyleDeclaration();

        style.defaultFactory = function() : void
        {
            this.showPromptWhenFocused = true;
        }

        FlexGlobals.topLevelApplication.styleManager.setStyleDeclaration("showPromptWhenFocused", style, false);
    }
    //call the static function immediately after the declaration
    initializeStyles();
}
} 

有什么想法吗?

【问题讨论】:

    标签: actionscript-3 apache-flex styles flex4 custom-component


    【解决方案1】:

    当你调用 getStyleDeclaration() 时传入你的类名,这样你就可以得到 WaterMarkTextInput 样式声明:

    var style : CSSStyleDeclaration = FlexGlobals.topLevelApplication.styleManager.getStyleDeclaration("WatermarkTextInput");
    

    然后在你为你的类设置样式时做同样的事情:

    FlexGlobals.topLevelApplication.styleManager.setStyleDeclaration("WatermarkTextInput", style, false);
    

    【讨论】:

    • 请记住,当您通过 MXML 实例化类时,defaultFactory 旨在包含 MXML 中设置的“默认值”。所以这个工厂可能无法在所有情况下都覆盖样式。我有更好的结果覆盖工厂而不是 defaultFactory。可能存在不包含您的样式属性的声明,因此您可能需要检查您确实获得的声明中的值。此外,Flex 4+ 中的所有 UIComponent 都引用了 stylemanager。你不需要使用 FlexGlobals(你也不应该)。
    • Amy - initializeStyles() 是静态的,所以它无法访问实例中的任何 styleManager 引用,不是吗?
    • 如何让祖先设置所有其他样式?还是在后代的静态函数执行时已经这样做了?调试,发现if(!style)为true好像还没有设置样式。
    • Sunil - 我已更改您的代码并添加了 if (style == null) style = FlexGlobals.topLevelApplication.styleManager.getStyleDeclaration("TextInput");但它仍然不会覆盖默认值。我也尝试过显式调用 parentStyle.defaultFactory() 等。
    【解决方案2】:

    尝试覆盖notifyStyleChangeInChildren()

    package com.santacruzsoftware.crafting.controls {
    
        import mx.core.FlexGlobals;
        import mx.styles.CSSStyleDeclaration;
        import mx.styles.StyleManager;
    
        import spark.components.TextInput;
    
        [Style(name="showPromptWhenFocused", inherit="yes", type="Boolean")]
        public class WatermarkTextInput extends TextInput {
    
            public var inheritStyles:boolean = true;
    
            private static function initializeStyles():void {
                var style : CSSStyleDeclaration = FlexGlobals.topLevelApplication.styleManager.getStyleDeclaration("showPromptWhenFocused");
                if (!style)
                    style = new CSSStyleDeclaration();
    
                style.defaultFactory = function():void {
                    this.showPromptWhenFocused = true;
                }
    
                FlexGlobals.topLevelApplication.styleManager.setStyleDeclaration("showPromptWhenFocused", style, false);
            }
    
            //call the static function immediately after the declaration
            initializeStyles();
    
            public override function notifyStyleChangeInChildren(styleProp:String, recursive:Boolean):void {
                if (!inheritStyles) {
                    switch(styleProp) {
                        case 'showPromptWhenFocused':
                            return;
                    }
                }
                super.notifyStyleChangeInChildren(styleProp, recursive);
            }
    
    }
    

    【讨论】:

    • 答案不应仅包含代码。为了让您的回答更有帮助,请说明您的代码和 OP 的代码之间的区别,并解释为什么它更好。
    • 对不起,我的英语很糟糕 =)
    • 我觉得你的英语不错。