大家好,一个问题一直困扰着小弟,就是c#中组件和控件的区别,但从visual studio中看表面的区别就是组件不能提供界面,而控件是有设计界面的,根据我在网上查询的资料获知:在编程领域内,组件其实就是一个可以复用并可以和其它对象交互的对象,而控件就是一个提供或实现了图形界面的组件,其实我感觉说的已经挺清楚了,但是我还是理解不透:1、什么时候应该选择使用组件呢,什么时候选择使用控件呢?2、就组件的可复用来说,用一个普通的类完全可以做到的啊,感觉组件类比普通类稍强一点的地方就是能够做到从vs的工具栏中拖拽到界面上,但是本质还是一个类的引用啊,为什么会出现组件呢?3、对实现同一个功能,控件是不是比组件耗费内存要多呢?希望懂的给个提示,小弟是个新手,所以问的问题难免有些肤浅,请大家见谅,谢谢啦,希望能用具体的例子加理论给些指点,我还有还来新手们不胜感激

解决方案 »

  1.   

    组件控件都能拖到界面里,组件不能查看设计器,你要想自己弄个能画的控件,就继承UserControl或control
    控件paint肯定比组件费时间
      

  2.   


    [ToolboxItem(true)]
        public partial class Station : Control
        {
            public Station()
            {
                InitializeComponent();
                System.Resources.ResourceManager rm =
                new System.Resources.ResourceManager("Ark.Controls.Business.Station",
                System.Reflection.Assembly.GetExecutingAssembly());
                try
                {
                    standardImage = (Bitmap)rm.GetObject("StandImage");
                    //TODO: if other tickets 
                }
                catch
                {            }
            }        protected override void OnPaint(PaintEventArgs pe)
            {
                base.OnPaint(pe);
            }        Bitmap standardImage;
            public Bitmap StandardImage
            {
                get { return standardImage; }
                set { standardImage = value; }
            }        Bitmap activeImage;
            public Bitmap ActiveImage
            {
                get { return activeImage; }
                set { activeImage = value; }
            }        private Int32 x1 = 0;
            private Int32 y1 = 0;
            private List<MapIndicator> mapIndicators = new List<MapIndicator>();
            private List<Point> points = new List<Point>();        protected override void OnMouseMove(MouseEventArgs e)
            {
                this.Cursor = System.Windows.Forms.Cursors.SizeAll;
                if (e.Button == System.Windows.Forms.MouseButtons.Left)
                {
                    x1 = e.X;
                    y1 = e.Y;
                }
                base.OnMouseMove(e);
            }        protected override void OnMouseUp(MouseEventArgs mevent)
            {
                if (x1 != 0 && y1 != 0)
                {
                    this.Left = this.Left + x1;
                    this.Top = this.Top + y1;
                }
                base.OnMouseUp(mevent);
            }        protected override void OnMouseDoubleClick(MouseEventArgs e)
            {
                if (mapIndicators.Count == 0)
                {
                    points.Add(new Point(this.Left, this.Top));
                    MapIndicator one = new MapIndicator(points[0]);
                    one.Show();
                    mapIndicators.Add(one);
                }
                base.OnMouseDoubleClick(e);
            }
      

  3.   


    public partial class LocationIndicator : UserControl
        {
            public LocationIndicator()
            {
                InitializeComponent();
                this.exLabel1.Size = new Size(57, 21);
                ChangeStatusSwitch = true;
                this.pictureBox1.Visible = true;
                this.mapIndicator1.Visible = false;
                this.exLabel1.Visible = false;
                this.ContextMenuStrip = this.contextMenuStrip1;
            }
            public LocationIndicator(Point LocationOfStation,Point LocationOfMap)
                : this()
            {
                try
                {
                    StationLocation = LocationOfStation;
                    MapLocation = LocationOfMap;
                    this.Left = StationLocation.X;
                    this.Top = StationLocation.Y;
                    this.mapIndicator1.usercontrollocation = LocationOfStation;
                }
                catch
                {
                }
            }        public LocationIndicator(Point LocationOfStation, Point LocationOfMap, String sinformation)
                : this()
            {
                StationLocation = LocationOfStation;
                MapLocation = LocationOfMap;
                this.Left = StationLocation.X;
                this.Top = StationLocation.Y;
                this.Information = sinformation;
                ChangeStatusSwitch = false;        }
            public Point StationLocation;
            private Point MapLocation;
            public String information;
            public EventHandler OperationAdd;
            public EventHandler OperationDelete;        public String Information
            {
                get { return information; }
                set { information = value; }
            }        private Int32 x1 = 0;
            private Int32 y1 = 0;
            private Int32 x2 = 0;
            private Int32 y2 = 0;        private bool changeStatusSwitch;        public bool ChangeStatusSwitch
            {
                get { return changeStatusSwitch; }
                set { changeStatusSwitch = value; }
            }
            public void ChangeStatus()
            {
                if (ChangeStatusSwitch == true)
                {
                    this.pictureBox1.Image = global::Ark.Controls.Business.Properties.Resources.StandardImage;
                    this.mapIndicator1.Visible = true;
                    this.mapIndicator1.Size = new Size(28, 21);
                    this.exLabel1.Visible = false;
                    if (this.Information != null)
                    {
                        this.mapIndicator1.Text = this.Information;
                    }
                    ChangeStatusSwitch = false;
                    this.mapIndicator1.Focus();
                }
                else
                {
                    this.pictureBox1.Image = global::Ark.Controls.Business.Properties.Resources.ActiveImage;
                    this.mapIndicator1.Visible = false;
                    this.exLabel1.Visible = true;
                    this.exLabel1.Text = this.Information;
                    ChangeStatusSwitch = true;
                }
            }        private void LocationIndicator_KeyPress(object sender, KeyPressEventArgs e)
            {
                if (e.KeyChar == '\r')
                {
                    if (this.mapIndicator1.Text == String.Empty)
                    {
                        MessageBox.Show("not empty");
                        return;
                    }
                    this.Information = this.mapIndicator1.Text;
                    this.ChangeStatus();
                    if (this.OperationAdd != null)
                    {
                        EventHandler tmp = this.OperationAdd;
                        tmp(sender, null);
                    }               
                }
            }        private void LocationIndicator_MouseMove(object sender, MouseEventArgs e)
            {
                this.Cursor = System.Windows.Forms.Cursors.SizeAll;
                if (e.Button == System.Windows.Forms.MouseButtons.Left)
                {
                    x1 = e.X;
                    y1 = e.Y;
                }
            }        private void LocationIndicator_MouseUp(object sender, MouseEventArgs e)
            {
                x2 = e.X;
                y2 = e.Y;            if (e.Button == MouseButtons.Left)
                {                if (x1 != 0 && y1 != 0)
                    {
                        this.Left = this.Left + x2 - x1;
                        this.Top = this.Top + y2 - y1;
                    }
                    if (x2 != x1 && y2 != y1)
                    {
                        this.ChangeStatus();
                    }
                }
            }        private void LocationIndicator_DoubleClick(object sender, EventArgs e)
            {
                this.ChangeStatus();
            }        void contextMenuStrip1_Opening(object sender, System.ComponentModel.CancelEventArgs e)
            {
                Control c = contextMenuStrip1.SourceControl as Control;
                contextMenuStrip1.Items.Clear();
                contextMenuStrip1.Items.Add("Edit");
                contextMenuStrip1.Items.Add("-");
                contextMenuStrip1.Items.Add("Delete");
                e.Cancel = false;
            }        private void contextMenuStrip1_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
            {
                this.ChangeStatus();
            }        public void editToolStripMenuItem_Click(object sender, EventArgs e)
            {
                this.ChangeStatus();
            }        public void deleteToolStripMenuItem_Click(object sender, EventArgs e)
            {
                this.Dispose();
                if (this.OperationDelete != null)
                {
                    EventHandler tmp = this.OperationDelete;
                    tmp(sender, null);
                }
            }
        }
      

  4.   

    但是在asp.net中与winform的习惯不同,几乎所有组件都叫做控件(这大概是因为所有控件都需要继承Render机制的缘故),不管它最终在浏览器端是否用户可见。
      

  5.   

    其实这个问题非常好回答,关键是你要去看.net的源代码(或者至少是接口)。当你开发一个组件,你需要从具有丰富的界面和交互机制的父类去继承,那么你做出来的当然就是控件了。如果你发觉根本不需要继承那写交互机制,只要继承更高层的,那么你就不是在开发控件了(那么当然也还是在开发组件)。比如许多入门书上叫做“Timer控件”的这个东西,如果你看源代码,它仅仅是组件,它没有继承控件父类接口才实现的有关“绘制界面、捕获用户焦点、支持拖放、返回windows窗口句柄、窗口线程切换、支捕获用户按键、坐标位置、改变大小、设置前景和背景颜色、设置可见性”等等功能。如果你开发一个组件,他不需要这些功能,而你从控件父类来继承设计,那么显然是画蛇添足了,由于实现有一堆自己根本不支持的功能方法接口,于是违反了面向对象设计的设计原则。
      

  6.   

    sp1234 的回答我看懂一些了,就是说不论是组件还是控件,都是为了复用而设计的对吧,需要界面的时候我们 用控件来实现,只是需要简单的功能而不需要界面就用组件来实现对吧?我所说的复用就用一次写好以后,以后在vs中就可以直接拖拽了,这样会非常方便,对于控件有图形界面这样做我能理解,那么组件和一个普通类还有什么区别了呢?它也没有界面,为什么还要单称组件呢?
      

  7.   

    .net的组件概念,基本上就是指可以支持在vs设计窗体上拖入、编程的类。所以它跟随便一个类也还是有区别。组件概念就好像是给普通类放上去特定的接口、或者特定的Attribute。只要非常重要,细微之处也可以自成体系。组件类非常简单,几乎没有内容,可是它是规定,vs等开发IDE环境就认识从组件类继承的子类、而不支持不从组件类继承的子类。
      

  8.   

    在.NET中有组件、控件和用户控件。其实从字面上已经可以理解各自的不同了。但是具体关系其实是从类的继承上来区别的。一般控件派生于:Control类,所以从此类派生出的称之为控件。一般组件派生于:Component类,所以从此类派生出的称之为组件。一般用户控件派生于:UserControl类,所以从该类派生出的称之为用户控件。(我们之所以这么叫其实是因为英文翻译上的习惯)他们之间的关系主要是:UserControl继承Control继承Component。
    但是具体在用时有什么区别呢?这主要是从设计的角度去考虑的。
    组件和一般类的区别:我们总是习惯于面向对象的设计方式。而对象则是由类实例化而来。我们强调万事万物皆对象,把对象看作设计的基本单元。
    所谓组件其实是面向组件的设计方式,我们把组件作为设计的基本单元。组件即为程序的组成部分。其实是构成程序的一个最基本的单元。一个组件其实可以包括多个类。这与传统的面向对象的设计方式有点区别。算是更高一层的封装。
    而控件和用户控件其实是组件按照具体的用途的一种划分,它们都是组件。控件的突出特点就是交互式组件。而用户控件则是将某些特定的组件或控件复合从而实现特定的业务功能。所以用户控件往往是从业务角度来设计的。
    其实,程序设计现在已经不在是简单的面向对象。
    从以往的面向过程到
    面向对象
    面向组件
    面向服务
    面向方向
    其实有很多。