none
请问如何能够重写一个 AutoSize 属性默认为 false 的 Label? RRS feed

  • 问题

  • 为什么这样写无效?

    class MyLabel : Label
    {
        const bool defaultAutoSize = false;
    
        public MyLabel()
        {
            AutoSize = defaultAutoSize;
        }
    
        [DefaultValue(defaultAutoSize)]
        public override bool AutoSize
        {
            get
            {
                return base.AutoSize;
            }
            set
            {
                base.AutoSize = value;
            }
        }
    }


    EFanZh



    • 已编辑 EFanZh 2012年3月16日 1:49
    2012年3月15日 15:05

答案

  • dear

    原谅我的粗心,忘了处理get

            private bool _AutoSize = false;
            [ToolboxItem(true)]
            [DefaultValue(false)]
            public bool AutoSize
            {
                get
                {
                    base.AutoSize = this._AutoSize;
                    return _AutoSize;
                }
                set
                {
                    this._AutoSize = value;
                    base.AutoSize = value;
                }
            }


    秘訣無它,唯勤而已 http://www.dotblogs.com.tw/yc421206/


    2012年3月16日 15:28
  • 暂时可以这样写:

    [ToolboxItem(true)]
    class MyLabel : Label
    {
    }

    虽然不太理解这个 ToolboxItemAttribute 的用法,但这样是可行的。

    • 已标记为答案 EFanZh 2012年3月17日 5:43
    • 已编辑 EFanZh 2012年3月17日 5:58
    2012年3月17日 5:40

全部回复

  • 您好,

    小弟有试了一下,一开始它的初始值的确是false.

    但是后来值又被改成了true。

    其实标签的AutoSize属性预设值本来就是false。

    小弟再研究一下。


    以上說明若有錯誤請指教,謝謝。
    亂馬客blog: http://www.dotblogs.com.tw/rainmaker/

    2012年3月16日 1:27
  • 根据 MSDN 文档(http://msdn.microsoft.com/zh-cn/library/system.windows.forms.label.autosize.aspx)可知:“使用设计器添加到窗体时,默认值为 true。当从代码实例化时,默认值为 false。”

    那么如何修改使用设计器时的默认值?


    EFanZh


    • 已编辑 EFanZh 2012年3月16日 2:27
    2012年3月16日 2:24
  • 您好,
    我想到一个笨方法,如果是第1次拉进来的话,而且要把它改成true就不要执行它,
    请参考以下的程式,谢谢!

    private bool isAssigned = false;
    public override bool AutoSize
    {
    	get
    	{
    		return base.AutoSize;
    	}
    	set
    	{
    		//如果是第1次拉进来的话,而且要把它改成true就不要执行它
    		if (DesignMode && value==true && isAssigned==false )
    		{
    			isAssigned = true;
    			return;
    		}
    		base.AutoSize = value;
    	}
    }


    以上說明若有錯誤請指教,謝謝。
    亂馬客blog: http://www.dotblogs.com.tw/rainmaker/

    2012年3月16日 2:57
  • 为什么这样写无效?

    class MyLabel : Label
    {
        const bool defaultAutoSize = false;
    
        public MyLabel()
        {
            AutoSize = defaultAutoSize;
        }
    
        [DefaultValue(defaultAutoSize)]
        public override bool AutoSize
        {
            get
            {
                return base.AutoSize;
            }
            set
            {
                base.AutoSize = value;
            }
        }
    }


    EFanZh



    dear

    因为你回传base.AutoSize,父类别的AutoSize是等于true的,你可以改写this后在改写base,且父类别有他自己的行为模式,就不要用父类别的属性了

            private bool _AutoSize = false;
            [DefaultValue(false)]
            public bool AutoSize
            {
                get { return this._AutoSize; }
                set
                {
                    this._AutoSize = value;
                    base.AutoSize = value;
                }
            }


    秘訣無它,唯勤而已 http://www.dotblogs.com.tw/yc421206/


    • 已编辑 余小章MVP 2012年3月16日 4:40
    • 已建议为答案 ThankfulHeartModerator 2012年3月16日 7:00
    • 已标记为答案 EFanZh 2012年3月16日 8:28
    • 取消答案标记 EFanZh 2012年3月17日 5:43
    • 取消建议作为答案 EFanZh 2012年3月17日 5:43
    2012年3月16日 4:36
  • 这种方法可行:

    class MyLabel : Label
    {
        [DefaultValue(false)]
        public override bool AutoSize
        {
            get
            {
                return base.AutoSize;
            }
            set
            {
                base.AutoSize = value;
            }
        }
    
        protected override void InitLayout()
        {
            base.InitLayout();
            base.AutoSize = false;
        }
    }

    • 已标记为答案 EFanZh 2012年3月16日 5:36
    • 取消答案标记 EFanZh 2012年3月16日 6:57
    • 已建议为答案 ThankfulHeartModerator 2012年3月16日 7:01
    • 已编辑 EFanZh 2012年3月16日 7:52
    • 已标记为答案 EFanZh 2012年3月16日 7:52
    • 取消答案标记 EFanZh 2012年3月17日 5:40
    • 取消建议作为答案 EFanZh 2012年3月17日 5:40
    2012年3月16日 5:36
  • 来迟了,真热闹啊,呵呵!

    以上的方法都可以,各有不同:

    1)小章的方法其实是定义了一个新的AutoSize取代原来从父类继承下来的(因为被屏蔽了)。

    2)后来作者的方法使用了IniLayout方法,这样会直接在拖拽到设计器上的时候就立即起到效果。

    对作者的补充:

    其实重写属性完全没有必要,更简化的做法:

    class MyLabel : Label
        {
            protected override void InitLayout()
            {
                base.InitLayout();
                base.AutoSize = false;
            }
        }


       QQ我:讨论(Talk)
    下载MSDN桌面工具(Vista,Win7)
    我的博客园
    慈善点击,点击此处

    • 已建议为答案 亂馬客 2012年3月16日 10:11
    2012年3月16日 7:06
    版主
  • 大家好,
    小弟來說說小弟的想法。
    1.小章大仔的做法,雖然AutoSize=false,但實際上還是AutoSize=true。因為不能調整大小!
    2.wei_Dong大仔的跟eFanZh相同,但更簡潔,但是Label好像會先做AdjustSize後,再把AutoSize設成false!
    3.亂馬客的沒有做過AdjustSize,所以拉出來的Size沒有改變!
    以上請參考下圖,

    經過討論後,小弟也收獲很多,謝謝大家!


    以上說明若有錯誤請指教,謝謝。
    亂馬客blog: http://www.dotblogs.com.tw/rainmaker/

    2012年3月16日 10:31
  • 补充说明:

    小章的这个问题其实是因为一开始直接返回了False,所以AutoSize本质还是True。解决方法是在属性编辑器中先设置True,然后再设置为False,这样即可调整大小了。


       QQ我:讨论(Talk)
    下载MSDN桌面工具(Vista,Win7)
    我的博客园
    慈善点击,点击此处

    2012年3月16日 11:59
    版主
  • 那么还有一个问题:使用窗体设计器添加 Label 时默认 AutoSize 为 true 的这一行为是在哪里定义的?

    • 已编辑 EFanZh 2012年3月16日 13:37
    2012年3月16日 13:34
  • dear

    原谅我的粗心,忘了处理get

            private bool _AutoSize = false;
            [ToolboxItem(true)]
            [DefaultValue(false)]
            public bool AutoSize
            {
                get
                {
                    base.AutoSize = this._AutoSize;
                    return _AutoSize;
                }
                set
                {
                    this._AutoSize = value;
                    base.AutoSize = value;
                }
            }


    秘訣無它,唯勤而已 http://www.dotblogs.com.tw/yc421206/


    2012年3月16日 15:28
  • 那么还有一个问题:使用窗体设计器添加 Label 时默认 AutoSize 为 true 的这一行为是在哪里定义的?

    在InitComponent事件中(Form的Designer.cs文件中,默认设置true)。 你可以拖拽一个正常的Label到里边去看看。

       QQ我:讨论(Talk)
    下载MSDN桌面工具(Vista,Win7)
    我的博客园
    慈善点击,点击此处

    2012年3月17日 3:12
    版主
  • 我的意思是,为什么使用窗体设计器添加 Label 时 InitComponent() 里会有“AutoSize = true”?

    在哪里定义了生成“AutoSize = true”的代码的这一行为?


    EFanZh


    • 已编辑 EFanZh 2012年3月17日 4:59
    2012年3月17日 4:59
  • 我的意思是,为什么使用窗体设计器添加 Label 时 InitComponent() 里会有“AutoSize = true”?

    在哪里定义了生成“AutoSize = true”的代码的这一行为?

    这是VS默认的一种行为。

       QQ我:讨论(Talk)
    下载MSDN桌面工具(Vista,Win7)
    我的博客园
    慈善点击,点击此处

    2012年3月17日 5:02
    版主
  • 查看 Label 定义,发现有这么一个东西:

    [ToolboxItem("System.Windows.Forms.Design.AutoSizeToolboxItem,System.Design, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")]
    public class Label : Control
    {
        // ...
    }

    在 .Net 源码中是这样的:

    namespace System.Windows.Forms.Design
    {
        using System;
        using System.ComponentModel;
        using System.ComponentModel.Design;
        using System.Diagnostics;
        using System.Diagnostics.CodeAnalysis;
        using System.Drawing.Design;
        using System.Runtime.Serialization;
        using System.Windows.Forms;
    
        // For Whidbey, we want to turn on AutoSize, AutoRelocate, and change the DefaultPadding 
        // from the values we shipped in RTM/Everett.  To avoid a breaking change, we use a 
        // custom toolbox item to apply these changes when the control is dropped.
        // 
        [Serializable]
        [SuppressMessage("Microsoft.Performance", "CA1812:AvoidUninstantiatedInternalClasses")] // this class is instantiated.
        internal class AutoSizeToolboxItem : ToolboxItem
        {
            public AutoSizeToolboxItem()
            {
            }
    
            public AutoSizeToolboxItem(Type toolType) : base(toolType)
            {
            }
    
            [SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")] // it's internal and nobody derives from this. 
            private AutoSizeToolboxItem(SerializationInfo info, StreamingContext context)
            {
                Deserialize(info, context);
            }
    
            protected override IComponent[] CreateComponentsCore(IDesignerHost host)
            {
                IComponent[] components = base.CreateComponentsCore(host);
    
                Debug.Assert(components != null && components.Length > 0, "ControlToolboxItem failed to create component.");
                Debug.Assert(components.Length == 1, "ControlToolboxItem did not create the correct number of components.");
                Debug.Assert(components.Length > 0 && components[0] is Control, "ControlToolboxItem did not create a control.");
    
                if (components != null && components.Length > 0 && components[0] is Control)
                {
                    Control control = components[0] as Control;
                    control.AutoSize = true;
                }
                return components;
            }
        }
    }

    我猜可能是这个原因。

    正在研究如何去除这个 Attribute。


    EFanZh


    • 已编辑 EFanZh 2012年3月17日 5:16
    2012年3月17日 5:15
  • 不太好办。这个class是intern的,照例而言无法修改的。

       QQ我:讨论(Talk)
    下载MSDN桌面工具(Vista,Win7)
    我的博客园
    慈善点击,点击此处

    2012年3月17日 5:19
    版主
  • 我重写一个继承 Label 的控件能移除(或者隐藏)这个特性吗?

    EFanZh

    2012年3月17日 5:23
  • 暂时可以这样写:

    [ToolboxItem(true)]
    class MyLabel : Label
    {
    }

    虽然不太理解这个 ToolboxItemAttribute 的用法,但这样是可行的。

    • 已标记为答案 EFanZh 2012年3月17日 5:43
    • 已编辑 EFanZh 2012年3月17日 5:58
    2012年3月17日 5:40
  • 我重写一个继承 Label 的控件能移除(或者隐藏)这个特性吗?
    要不你尝试完全拷贝这个AutoSizeToolboxItem类代码到你自己的某个cs文件,然后就把AutoSize改为false(其余不改变)。然后在重写一个MyLabel:Control(代码拷贝原来发射出来的源代码)试试看。

       QQ我:讨论(Talk)
    下载MSDN桌面工具(Vista,Win7)
    我的博客园
    慈善点击,点击此处

    2012年3月17日 5:42
    版主
  • 这个“[ToolboxItem(true)]”不太理解,而且是不是应该放在 class 上面?

    EFanZh

    2012年3月17日 5:42
  • 这个“[ToolboxItem(true)]”不太理解,而且是不是应该放在 class 上面?

    EFanZh

    是的,是类属性,放到类上面。

    另外:ToolBoxItem(true)一切属性均按照其默认值进行设置,否则的话就按照VS那个自动拖拽到winForm界面上自动生成的来走。

    另外:请把乱马客的答案标记一下,谢谢!


       QQ我:讨论(Talk)
    下载MSDN桌面工具(Vista,Win7)
    我的博客园
    慈善点击,点击此处

    2012年3月17日 5:58
    版主
  • dear

    參考以下,他主要是用在VS工具上.......

    http://msdn.microsoft.com/zh-cn/library/system.drawing.design.toolboxitem%28VS.80%29.aspx

    我有一些帖子是有关UserControl,基本上那些Attribute大部份都是给VS设计阶段的时后用的

    http://www.dotblogs.com.tw/yc421206/category/3913.aspx


    秘訣無它,唯勤而已 http://www.dotblogs.com.tw/yc421206/

    2012年3月17日 17:55