Como: Aplicar atributos in Windows Forms Controls

Para desenvolver componentes e controles que interajam corretamente com o ambiente de design e executado corretamente em time de executar, você precisa aplicar atributos corretamente a classes e membros.

Exemplo

O exemplo de código a seguir demonstra como usar vários atributos em um controle personalizado.O controle demonstra um recurso de registrar registrar registrar em log simples.Quando o controle está limite a uma fonte de dados, ele exibe os valores enviados pela fonte de dados em um DataGridView controle. Se um valor excede o valor especificado pelo Threshold propriedade, um ThresholdExceeded evento é gerado.

The AttributesDemoControl registra os valores com um LogEntry classe. The LogEntry classe é uma classe de modelo, o que significa que é parametrizado no tipo que ele registra. Por exemplo, se o AttributesDemoControl está fazendo o valores do tipo float, cada LogEntry instância é declarada e usada sistema autônomo a seguir.

        // This method handles the timer's Elapsed event. It queries
        // the performance counter for the next value, packs the 
        // value in a LogEntry object, and adds the new LogEntry to
        // the list managed by the BindingSource.
        private void timer1_Elapsed(
            object sender, 
            System.Timers.ElapsedEventArgs e)
        {   
            // Get the latest value from the performance counter.
            float val = this.performanceCounter1.NextValue();

            // The performance counter returns values of type float, 
            // but any type that implements the IComparable interface
            // will work.
            LogEntry<float> entry = new LogEntry<float>(val, DateTime.Now);

            // Add the new LogEntry to the BindingSource list.
            this.bindingSource1.Add(entry);
        }
Observação:

Porque LogEntry é parametrizado por um tipo arbitrário, ele deverá usar reflexão para operar em tipo de parâmetro. Para que o recurso de limiar funcionar, o parâmetro tipo T deve implementar o IComparable interface.

O formulário que hospeda o AttributesDemoControl consulta periodicamente um contador de desempenho. Cada valor é empacotado em um LogEntry do tipo apropriado e adicionado do formulário BindingSource. The AttributesDemoControl recebe o valor por meio de sua vinculação de dados e exibe o valor em um DataGridView controle.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Diagnostics;
using System.Drawing;
using System.Data;
using System.Reflection;
using System.Text;
using System.Windows.Forms;

// This sample demonstrates the use of various attributes for
// authoring a control. 
namespace AttributesDemoControlLibrary
{
    // This is the event handler delegate for the ThresholdExceeded event.
    public delegate void ThresholdExceededEventHandler(ThresholdExceededEventArgs e);

    // This control demonstrates a simple logging capability. 
    [ComplexBindingProperties("DataSource", "DataMember")]
    [DefaultBindingProperty("TitleText")]
    [DefaultEvent("ThresholdExceeded")]
    [DefaultProperty("Threshold")]
    [HelpKeywordAttribute(typeof(UserControl))]
    [ToolboxItem("System.Windows.Forms.Design.AutoSizeToolboxItem,System.Design")]
    public class AttributesDemoControl : UserControl
    {

        // This backs the Threshold property.
        private object thresholdValue;

        // The default fore color value for DataGridView cells that
        // contain values that exceed the threshold.
        private static Color defaultAlertForeColorValue = Color.White;

        // The default back color value for DataGridView cells that
        // contain values that exceed the threshold.
        private static Color defaultAlertBackColorValue = Color.Red;

        // The ambient color value.
        private static Color ambientColorValue = Color.Empty;

        // The fore color value for DataGridView cells that
        // contain values that exceed the threshold.
        private Color alertForeColorValue = defaultAlertForeColorValue;

        // The back color value for DataGridView cells that
        // contain values that exceed the threshold.
        private Color alertBackColorValue = defaultAlertBackColorValue;

        // Child controls that comprise this UserControl.
        private TableLayoutPanel tableLayoutPanel1;
        private DataGridView dataGridView1;
        private Label label1;

        // Required for designer support.
        private System.ComponentModel.IContainer components = null;

        // Default constructor.
        public AttributesDemoControl()
        {
            InitializeComponent();
        }

        [Category("Appearance")]
        [Description("The title of the log data.")]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
        [Localizable(true)]
        [HelpKeywordAttribute("AttributesDemoControlLibrary.AttributesDemoControl.TitleText")]
        public string TitleText
        {
            get
            {
                return this.label1.Text;
            }

            set
            {
                this.label1.Text = value;
            }
        }

        // The inherited Text property is hidden at design time and 
        // raises an exception at run time. This enforces a requirement
        // that client code uses the TitleText property instead.
        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public override string Text
        {
            get
            {
                throw new NotSupportedException();
            }
            set
            {
                throw new NotSupportedException();
            }
        }

        [AmbientValue(typeof(Color), "Empty")]
        [Category("Appearance")]
        [DefaultValue(typeof(Color), "White")]
        [Description("The color used for painting alert text.")]
        public Color AlertForeColor
        {
            get
            {
                if (this.alertForeColorValue == Color.Empty &&
                    this.Parent != null)
                {
                    return Parent.ForeColor;
                }

                return this.alertForeColorValue;
            }

            set
            {
                this.alertForeColorValue = value;
            }
        }

        // This method is used by designers to enable resetting the
        // property to its default value.
        public void ResetAlertForeColor()
        {
            this.AlertForeColor = AttributesDemoControl.defaultAlertForeColorValue;
        }

        // This method indicates to designers whether the property
        // value is different from the ambient value, in which case
        // the designer should persist the value.
        private bool ShouldSerializeAlertForeColor()
        {
            return (this.alertForeColorValue != AttributesDemoControl.ambientColorValue);
        }

        [AmbientValue(typeof(Color), "Empty")]
        [Category("Appearance")]
        [DefaultValue(typeof(Color), "Red")]
        [Description("The background color for painting alert text.")]
        public Color AlertBackColor
        {
            get
            {
                if (this.alertBackColorValue == Color.Empty &&
                    this.Parent != null)
                {
                    return Parent.BackColor;
                }

                return this.alertBackColorValue;
            }

            set
            {
                this.alertBackColorValue = value;
            }
        }

        // This method is used by designers to enable resetting the
        // property to its default value.
        public void ResetAlertBackColor()
        {
            this.AlertBackColor = AttributesDemoControl.defaultAlertBackColorValue;
        }

        // This method indicates to designers whether the property
        // value is different from the ambient value, in which case
        // the designer should persist the value.
        private bool ShouldSerializeAlertBackColor()
        {
            return (this.alertBackColorValue != AttributesDemoControl.ambientColorValue);
        }

        [Category("Data")]
        [Description("Indicates the source of data for the control.")]
        [RefreshProperties(RefreshProperties.Repaint)]
        [AttributeProvider(typeof(IListSource))]
        public object DataSource
        {
            get
            {
                return this.dataGridView1.DataSource;
            }

            set
            {
                this.dataGridView1.DataSource = value;
            }
        }

        [Category("Data")]
        [Description("Indicates a sub-list of the data source to show in the control.")]
        public string DataMember
        {
            get
            {
                return this.dataGridView1.DataMember;
            }

            set
            {
                this.dataGridView1.DataMember = value;
            }
        }

        // This property would normally have its BrowsableAttribute 
        // set to false, but this code demonstrates using 
        // ReadOnlyAttribute, so BrowsableAttribute is true to show 
        // it in any attached PropertyGrid control.
        [Browsable(true)]
        [Category("Behavior")]
        [Description("The timestamp of the latest entry.")]
        [ReadOnly(true)]
        public DateTime CurrentLogTime
        {
            get
            {
                int lastRowIndex = 
                    this.dataGridView1.Rows.GetLastRow(
                    DataGridViewElementStates.Visible);

                if (lastRowIndex > -1)
                {
                    DataGridViewRow lastRow = this.dataGridView1.Rows[lastRowIndex];
                    DataGridViewCell lastCell = lastRow.Cells["EntryTime"];
                    return ((DateTime)lastCell.Value);
                }
                else
                {
                    return DateTime.MinValue;
                }
            }

            set
            {
            }
        }

        [Category("Behavior")]
        [Description("The value above which the ThresholdExceeded event will be raised.")]
        public object Threshold
        {
            get
            {
                return this.thresholdValue;
            }

            set
            {
                this.thresholdValue = value;
            }
        }

        // This property exists only to demonstrate the 
        // PasswordPropertyText attribute. When this control 
        // is attached to a PropertyGrid control, the returned 
        // string will be displayed with obscuring characters
        // such as asterisks. This property has no other effect.
        [Category("Security")]
        [Description("Demonstrates PasswordPropertyTextAttribute.")]
        [PasswordPropertyText(true)]
        public string Password
        {
            get
            {
                return "This is a demo password.";
            }
        }

        // This property exists only to demonstrate the 
        // DisplayName attribute. When this control 
        // is attached to a PropertyGrid control, the
        // property will be appear as "RenamedProperty"
        // instead of "MisnamedProperty".
        [Description("Demonstrates DisplayNameAttribute.")]
        [DisplayName("RenamedProperty")]
        public bool MisnamedProperty
        {
            get
            {
                return true;
            }
        }

        // This is the declaration for the ThresholdExceeded event.
        public event ThresholdExceededEventHandler ThresholdExceeded;

        #region Implementation

        // This is the event handler for the DataGridView control's 
        // CellFormatting event. Handling this event allows the 
        // AttributesDemoControl to examine the incoming log entries
        // from the data source as they arrive.
        //
        // If the cell for which this event is raised holds the
        // log entry's timestamp, the cell value is formatted with 
        // the full date/time pattern. 
        // 
        // Otherwise, the cell's value is assumed to hold the log 
        // entry value. If the value exceeds the threshold value, 
        // the cell is painted with the colors specified by the
        // AlertForeColor and AlertBackColor properties, after which
        // the ThresholdExceeded is raised. For this comparison to 
        // succeed, the log entry's type must implement the IComparable 
        // interface.
        private void dataGridView1_CellFormatting(
            object sender,
            DataGridViewCellFormattingEventArgs e)
        {
            try
            {
                if (e.Value != null)
                {
                    if (e.Value is DateTime)
                    {
                        // Display the log entry time with the 
                        // full date/time pattern (long time).
                        e.CellStyle.Format = "F";
                    }
                    else
                    {
                        // Scroll to the most recent entry.
                        DataGridViewRow row = this.dataGridView1.Rows[e.RowIndex];
                        DataGridViewCell cell = row.Cells[e.ColumnIndex];
                        this.dataGridView1.FirstDisplayedCell = cell;

                        if (this.thresholdValue != null)
                        {
                            // Get the type of the log entry.
                            object val = e.Value;
                            Type paramType = val.GetType();

                            // Compare the log entry value to the threshold value.
                            // Use reflection to call the CompareTo method on the
                            // template parameter's type. 
                            int compareVal = (int)paramType.InvokeMember(
                                "CompareTo",
                                BindingFlags.Default | BindingFlags.InvokeMethod,
                                null,
                                e.Value,
                                new object[] { this.thresholdValue },
                                System.Globalization.CultureInfo.InvariantCulture);

                            // If the log entry value exceeds the threshold value,
                            // set the cell's fore color and back color properties
                            // and raise the ThresholdExceeded event.
                            if (compareVal > 0)
                            {
                                e.CellStyle.BackColor = this.alertBackColorValue;
                                e.CellStyle.ForeColor = this.alertForeColorValue;

                                ThresholdExceededEventArgs teea =
                                    new ThresholdExceededEventArgs(
                                    this.thresholdValue,
                                    e.Value);
                                this.ThresholdExceeded(teea);
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Trace.WriteLine(ex.Message);
            }
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        private void InitializeComponent()
        {
            System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle1 = new System.Windows.Forms.DataGridViewCellStyle();
            this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
            this.dataGridView1 = new System.Windows.Forms.DataGridView();
            this.label1 = new System.Windows.Forms.Label();
            this.tableLayoutPanel1.SuspendLayout();
            ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).BeginInit();
            this.SuspendLayout();
            // 
            // tableLayoutPanel1
            // 
            this.tableLayoutPanel1.AutoSize = true;
            this.tableLayoutPanel1.ColumnCount = 1;
            this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 100F));
            this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 100F));
            this.tableLayoutPanel1.Controls.Add(this.dataGridView1, 0, 1);
            this.tableLayoutPanel1.Controls.Add(this.label1, 0, 0);
            this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill;
            this.tableLayoutPanel1.Location = new System.Drawing.Point(10, 10);
            this.tableLayoutPanel1.Name = "tableLayoutPanel1";
            this.tableLayoutPanel1.Padding = new System.Windows.Forms.Padding(10);
            this.tableLayoutPanel1.RowCount = 2;
            this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 10F));
            this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 80F));
            this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 10F));
            this.tableLayoutPanel1.Size = new System.Drawing.Size(425, 424);
            this.tableLayoutPanel1.TabIndex = 0;
            // 
            // dataGridView1
            // 
            this.dataGridView1.AllowUserToAddRows = false;
            this.dataGridView1.AllowUserToDeleteRows = false;
            this.dataGridView1.AllowUserToOrderColumns = true;
            this.dataGridView1.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
            this.dataGridView1.AutoSizeRowsMode = System.Windows.Forms.DataGridViewAutoSizeRowsMode.AllCells;
            dataGridViewCellStyle1.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft;
            dataGridViewCellStyle1.BackColor = System.Drawing.SystemColors.Control;
            dataGridViewCellStyle1.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            dataGridViewCellStyle1.ForeColor = System.Drawing.SystemColors.WindowText;
            dataGridViewCellStyle1.SelectionBackColor = System.Drawing.SystemColors.Highlight;
            dataGridViewCellStyle1.SelectionForeColor = System.Drawing.SystemColors.HighlightText;
            dataGridViewCellStyle1.WrapMode = System.Windows.Forms.DataGridViewTriState.False;
            this.dataGridView1.ColumnHeadersDefaultCellStyle = dataGridViewCellStyle1;
            this.dataGridView1.ColumnHeadersHeight = 4;
            this.dataGridView1.Dock = System.Windows.Forms.DockStyle.Fill;
            this.dataGridView1.Location = new System.Drawing.Point(13, 57);
            this.dataGridView1.Name = "dataGridView1";
            this.dataGridView1.ReadOnly = true;
            this.dataGridView1.RowHeadersVisible = false;
            this.dataGridView1.Size = new System.Drawing.Size(399, 354);
            this.dataGridView1.TabIndex = 1;
            this.dataGridView1.CellFormatting += new System.Windows.Forms.DataGridViewCellFormattingEventHandler(this.dataGridView1_CellFormatting);
            // 
            // label1
            // 
            this.label1.AutoSize = true;
            this.label1.BackColor = System.Drawing.SystemColors.Control;
            this.label1.Dock = System.Windows.Forms.DockStyle.Fill;
            this.label1.Location = new System.Drawing.Point(13, 13);
            this.label1.Name = "label1";
            this.label1.Size = new System.Drawing.Size(399, 38);
            this.label1.TabIndex = 2;
            this.label1.Text = "label1";
            this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
            // 
            // AttributesDemoControl
            // 
            this.Controls.Add(this.tableLayoutPanel1);
            this.Name = "AttributesDemoControl";
            this.Padding = new System.Windows.Forms.Padding(10);
            this.Size = new System.Drawing.Size(445, 444);
            this.tableLayoutPanel1.ResumeLayout(false);
            this.tableLayoutPanel1.PerformLayout();
            ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).EndInit();
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        #endregion
    }

    // This is the EventArgs class for the ThresholdExceeded event.
    public class ThresholdExceededEventArgs : EventArgs
    {
        private object thresholdValue = null;
        private object exceedingValue = null;

        public ThresholdExceededEventArgs(
            object thresholdValue,
            object exceedingValue)
        {
            this.thresholdValue = thresholdValue;
            this.exceedingValue = exceedingValue;
        }

        public object ThresholdValue
        {
            get
            {
                return this.thresholdValue;
            }
        }

        public object ExceedingValue
        {
            get
            {
                return this.exceedingValue;
            }
        }
    }

    // This class encapsulates a log entry. It is a parameterized 
    // type (also known as a template class). The parameter type T
    // defines the type of data being logged. For threshold detection
    // to work, this type must implement the IComparable interface.
    [TypeConverter("LogEntryTypeConverter")]
    public class LogEntry<T> where T : IComparable
    {
        private T entryValue;
        private DateTime entryTimeValue;

        public LogEntry(
            T value,
            DateTime time)
        {
            this.entryValue = value;
            this.entryTimeValue = time;
        }

        public T Entry
        {
            get
            {
                return this.entryValue;
            }
        }

        public DateTime EntryTime
        {
            get
            {
                return this.entryTimeValue;
            }
        }

        // This is the TypeConverter for the LogEntry class.
        public class LogEntryTypeConverter : TypeConverter
        {
            public override bool CanConvertFrom(
                ITypeDescriptorContext context,
                Type sourceType)
            {
                if (sourceType == typeof(string))
                {
                    return true;
                }

                return base.CanConvertFrom(context, sourceType);
            }

            public override object ConvertFrom(
                ITypeDescriptorContext context,
                System.Globalization.CultureInfo culture,
                object value)
            {
                if (value is string)
                {
                    string[] v = ((string)value).Split(new char[] { '|' });

                    Type paramType = typeof(T);
                    T entryValue = (T)paramType.InvokeMember(
                        "Parse",
                        BindingFlags.Static | BindingFlags.Public | BindingFlags.InvokeMethod,
                        null,
                        null,
                        new string[] { v[0] },
                        culture);

                    return new LogEntry<T>(
                        entryValue,
                        DateTime.Parse(v[2]));
                }

                return base.ConvertFrom(context, culture, value);
            }

            public override object ConvertTo(
                ITypeDescriptorContext context,
                System.Globalization.CultureInfo culture,
                object value,
                Type destinationType)
            {
                if (destinationType == typeof(string))
                {
                    LogEntry<T> le = value as LogEntry<T>;

                    string stringRepresentation =
                        String.Format("{0} | {1}",
                        le.Entry,
                        le.EntryTime);

                    return stringRepresentation;
                }

                return base.ConvertTo(context, culture, value, destinationType);
            }
        }
    }
}
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Windows.Forms;
using AttributesDemoControlLibrary;

// This sample demonstrates using the AttributesDemoControl to log
// data from a data source. 
namespace AttributesDemoControlTest
{
    public class Form1 : Form
    {   
        private BindingSource bindingSource1;
        private System.Diagnostics.PerformanceCounter performanceCounter1;
        private Button startButton;
        private Button stopButton;
        private System.Timers.Timer timer1;
        private ToolStripStatusLabel statusStripPanel1;
        private NumericUpDown numericUpDown1;
        private GroupBox groupBox1;
        private GroupBox groupBox2;
        private TableLayoutPanel tableLayoutPanel1;
        private AttributesDemoControl attributesDemoControl1;
        private System.ComponentModel.IContainer components = null;

        // This form uses an AttributesDemoControl to display a stream
        // of LogEntry objects. The data stream is generated by polling
        // a performance counter and communicating the counter values 
        // to the control with data binding.
        public Form1()
        {
            InitializeComponent();

            // Set the initial value of the threshold up/down control 
            // to the control's threshold value.
            this.numericUpDown1.Value = 
                (decimal)(float)this.attributesDemoControl1.Threshold;

            // Assign the performance counter's name to the control's 
            // title text.
            this.attributesDemoControl1.TitleText = 
                this.performanceCounter1.CounterName;
        }

        // This method handles the ThresholdExceeded event. It posts
        // the value that exceeded the threshold to the status strip.  
        private void attributesDemoControl1_ThresholdExceeded(
            ThresholdExceededEventArgs e)
        {
            string msg = String.Format(
                "{0}: Value {1} exceeded threshold {2}", 
                this.attributesDemoControl1.CurrentLogTime, 
                e.ExceedingValue, 
                e.ThresholdValue);

            this.ReportStatus( msg );
        }

        // This method handles the timer's Elapsed event. It queries
        // the performance counter for the next value, packs the 
        // value in a LogEntry object, and adds the new LogEntry to
        // the list managed by the BindingSource.
        private void timer1_Elapsed(
            object sender, 
            System.Timers.ElapsedEventArgs e)
        {   
            // Get the latest value from the performance counter.
            float val = this.performanceCounter1.NextValue();

            // The performance counter returns values of type float, 
            // but any type that implements the IComparable interface
            // will work.
            LogEntry<float> entry = new LogEntry<float>(val, DateTime.Now);

            // Add the new LogEntry to the BindingSource list.
            this.bindingSource1.Add(entry);
        }

        private void numericUpDown1_ValueChanged(object sender, EventArgs e)
        {
            this.attributesDemoControl1.Threshold = 
                (float)this.numericUpDown1.Value;

            string msg = String.Format(
                "Threshold changed to {0}", 
                this.attributesDemoControl1.Threshold);

            this.ReportStatus(msg);
        }

        private void startButton_Click(object sender, EventArgs e)
        {
            this.ReportStatus(DateTime.Now + ": Starting");

            this.timer1.Start();
        }

        private void stopButton_Click(object sender, EventArgs e)
        {
            this.ReportStatus(DateTime.Now + ": Stopping");

            this.timer1.Stop();
        }

        private void ReportStatus(string msg)
        {
            if (msg != null)
            {
                this.statusStripPanel1.Text = msg;
            }
        }

        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.Run(new Form1());
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        private void InitializeComponent()
        {
            this.components = new System.ComponentModel.Container();
            this.bindingSource1 = new System.Windows.Forms.BindingSource(this.components);
            this.performanceCounter1 = new System.Diagnostics.PerformanceCounter();
            this.startButton = new System.Windows.Forms.Button();
            this.stopButton = new System.Windows.Forms.Button();
            this.timer1 = new System.Timers.Timer();
            this.statusStripPanel1 = new System.Windows.Forms.ToolStripStatusLabel();
            this.numericUpDown1 = new System.Windows.Forms.NumericUpDown();
            this.groupBox1 = new System.Windows.Forms.GroupBox();
            this.groupBox2 = new System.Windows.Forms.GroupBox();
            this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
            this.attributesDemoControl1 = new AttributesDemoControlLibrary.AttributesDemoControl();
            ((System.ComponentModel.ISupportInitialize)(this.bindingSource1)).BeginInit();
            ((System.ComponentModel.ISupportInitialize)(this.performanceCounter1)).BeginInit();
            ((System.ComponentModel.ISupportInitialize)(this.timer1)).BeginInit();
            
            
            ((System.ComponentModel.ISupportInitialize)(this.numericUpDown1)).BeginInit();
            this.groupBox1.SuspendLayout();
            this.groupBox2.SuspendLayout();
            this.tableLayoutPanel1.SuspendLayout();
            this.SuspendLayout();
            // 
            // performanceCounter1
            // 
            this.performanceCounter1.CategoryName = ".NET CLR Memory";
            this.performanceCounter1.CounterName = "Gen 0 heap size";
            this.performanceCounter1.InstanceName = "_Global_";
            // 
            // startButton
            // 
            this.startButton.Location = new System.Drawing.Point(31, 25);
            this.startButton.Name = "startButton";
            this.startButton.TabIndex = 1;
            this.startButton.Text = "Start";
            this.startButton.Click += new System.EventHandler(this.startButton_Click);
            // 
            // stopButton
            // 
            this.stopButton.Location = new System.Drawing.Point(112, 25);
            this.stopButton.Name = "stopButton";
            this.stopButton.TabIndex = 2;
            this.stopButton.Text = "Stop";
            this.stopButton.Click += new System.EventHandler(this.stopButton_Click);
            // 
            // timer1
            // 
            this.timer1.Interval = 1000;
            this.timer1.SynchronizingObject = this;
            this.timer1.Elapsed += new System.Timers.ElapsedEventHandler(this.timer1_Elapsed);
            // 
            // statusStripPanel1
            // 
            this.statusStripPanel1.BorderStyle = System.Windows.Forms.Border3DStyle.SunkenOuter;
            this.statusStripPanel1.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;
            this.statusStripPanel1.Name = "statusStripPanel1";
            this.statusStripPanel1.Text = "Ready";
            // 
            // numericUpDown1
            // 
            this.numericUpDown1.Location = new System.Drawing.Point(37, 29);
            this.numericUpDown1.Maximum = new decimal(new int[] {
            1410065408,
            2,
            0,
            0});
            this.numericUpDown1.Name = "numericUpDown1";
            this.numericUpDown1.TabIndex = 7;
            this.numericUpDown1.ValueChanged += new System.EventHandler(this.numericUpDown1_ValueChanged);
            // 
            // groupBox1
            // 
            this.groupBox1.Anchor = System.Windows.Forms.AnchorStyles.None;
            this.groupBox1.Controls.Add(this.numericUpDown1);
            this.groupBox1.Location = new System.Drawing.Point(280, 326);
            this.groupBox1.Name = "groupBox1";
            this.groupBox1.Size = new System.Drawing.Size(200, 70);
            this.groupBox1.TabIndex = 13;
            this.groupBox1.TabStop = false;
            this.groupBox1.Text = "Threshold Value";
            // 
            // groupBox2
            // 
            this.groupBox2.Anchor = System.Windows.Forms.AnchorStyles.None;
            this.groupBox2.Controls.Add(this.startButton);
            this.groupBox2.Controls.Add(this.stopButton);
            this.groupBox2.Location = new System.Drawing.Point(26, 327);
            this.groupBox2.Name = "groupBox2";
            this.groupBox2.Size = new System.Drawing.Size(214, 68);
            this.groupBox2.TabIndex = 14;
            this.groupBox2.TabStop = false;
            this.groupBox2.Text = "Logging";
            // 
            // tableLayoutPanel1
            // 
            this.tableLayoutPanel1.ColumnCount = 2;
            this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
            this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
            this.tableLayoutPanel1.Controls.Add(this.groupBox2, 0, 1);
            this.tableLayoutPanel1.Controls.Add(this.groupBox1, 1, 1);
            this.tableLayoutPanel1.Controls.Add(this.attributesDemoControl1, 0, 0);
            this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill;
            this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 0);
            this.tableLayoutPanel1.Name = "tableLayoutPanel1";
            this.tableLayoutPanel1.Padding = new System.Windows.Forms.Padding(10);
            this.tableLayoutPanel1.RowCount = 2;
            this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 80F));
            this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 20F));
            this.tableLayoutPanel1.Size = new System.Drawing.Size(514, 411);
            this.tableLayoutPanel1.TabIndex = 15;
            // 
            // attributesDemoControl1
            // 
            this.tableLayoutPanel1.SetColumnSpan(this.attributesDemoControl1, 2);
            this.attributesDemoControl1.DataMember = "";
            this.attributesDemoControl1.DataSource = this.bindingSource1;
            this.attributesDemoControl1.Dock = System.Windows.Forms.DockStyle.Fill;
            this.attributesDemoControl1.Location = new System.Drawing.Point(13, 13);
            this.attributesDemoControl1.Name = "attributesDemoControl1";
            this.attributesDemoControl1.Padding = new System.Windows.Forms.Padding(10);
            this.attributesDemoControl1.Size = new System.Drawing.Size(488, 306);
            this.attributesDemoControl1.TabIndex = 0;
            this.attributesDemoControl1.Threshold = 200000F;
            this.attributesDemoControl1.TitleText = "TITLE";
            this.attributesDemoControl1.ThresholdExceeded += new AttributesDemoControlLibrary.ThresholdExceededEventHandler(this.attributesDemoControl1_ThresholdExceeded);
            // 
            // Form1
            // 
            this.BackColor = System.Drawing.SystemColors.Control;
            this.ClientSize = new System.Drawing.Size(514, 430);
            this.Controls.Add(this.tableLayoutPanel1);
            this.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.Name = "Form1";
            this.Text = "Form1";
            ((System.ComponentModel.ISupportInitialize)(this.bindingSource1)).EndInit();
            ((System.ComponentModel.ISupportInitialize)(this.performanceCounter1)).EndInit();
            ((System.ComponentModel.ISupportInitialize)(this.timer1)).EndInit();
            ((System.ComponentModel.ISupportInitialize)(this.numericUpDown1)).EndInit();
            this.groupBox1.ResumeLayout(false);
            this.groupBox2.ResumeLayout(false);
            this.tableLayoutPanel1.ResumeLayout(false);
            this.ResumeLayout(false);
            this.PerformLayout();

        }
    }
}

O primeiro exemplo de código é o AttributesDemoControl implementação. O segundo exemplo de código demonstra um formulário que usa o AttributesDemoControl.

Atributos de nível de classe

Alguns atributos são aplicados no nível de classe.O exemplo de código a seguir mostra os atributos que normalmente são aplicados a um controle Windows Forms.

// This control demonstrates a simple logging capability. 
[ComplexBindingProperties("DataSource", "DataMember")]
[DefaultBindingProperty("TitleText")]
[DefaultEvent("ThresholdExceeded")]
[DefaultProperty("Threshold")]
[HelpKeywordAttribute(typeof(UserControl))]
[ToolboxItem("System.Windows.Forms.Design.AutoSizeToolboxItem,System.Design")]
public class AttributesDemoControl : UserControl
{

Atributo de TypeConverter

TypeConverterAttribute é outro atributo de nível de classe usado com freqüência. O exemplo de código a seguir mostra o uso de LogEntry classe. Este exemplo também mostra uma implementação de um TypeConverter para o LogEntry tipo, chamado LogEntryTypeConverter.

// This class encapsulates a log entry. It is a parameterized 
// type (also known as a template class). The parameter type T
// defines the type of data being logged. For threshold detection
// to work, this type must implement the IComparable interface.
[TypeConverter("LogEntryTypeConverter")]
public class LogEntry<T> where T : IComparable
{
    private T entryValue;
    private DateTime entryTimeValue;

    public LogEntry(
        T value,
        DateTime time)
    {
        this.entryValue = value;
        this.entryTimeValue = time;
    }

    public T Entry
    {
        get
        {
            return this.entryValue;
        }
    }

    public DateTime EntryTime
    {
        get
        {
            return this.entryTimeValue;
        }
    }

    // This is the TypeConverter for the LogEntry class.
    public class LogEntryTypeConverter : TypeConverter
    {
        public override bool CanConvertFrom(
            ITypeDescriptorContext context,
            Type sourceType)
        {
            if (sourceType == typeof(string))
            {
                return true;
            }

            return base.CanConvertFrom(context, sourceType);
        }

        public override object ConvertFrom(
            ITypeDescriptorContext context,
            System.Globalization.CultureInfo culture,
            object value)
        {
            if (value is string)
            {
                string[] v = ((string)value).Split(new char[] { '|' });

                Type paramType = typeof(T);
                T entryValue = (T)paramType.InvokeMember(
                    "Parse",
                    BindingFlags.Static | BindingFlags.Public | BindingFlags.InvokeMethod,
                    null,
                    null,
                    new string[] { v[0] },
                    culture);

                return new LogEntry<T>(
                    entryValue,
                    DateTime.Parse(v[2]));
            }

            return base.ConvertFrom(context, culture, value);
        }

        public override object ConvertTo(
            ITypeDescriptorContext context,
            System.Globalization.CultureInfo culture,
            object value,
            Type destinationType)
        {
            if (destinationType == typeof(string))
            {
                LogEntry<T> le = value as LogEntry<T>;

                string stringRepresentation =
                    String.Format("{0} | {1}",
                    le.Entry,
                    le.EntryTime);

                return stringRepresentation;
            }

            return base.ConvertTo(context, culture, value, destinationType);
        }
    }
}

Atributos de nível de membro

Alguns atributos são aplicados no nível do membro.Os exemplos de código a seguir mostram alguns atributos são aplicados normalmente a propriedades de controles Windows Forms.

[Category("Appearance")]
[Description("The title of the log data.")]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
[Localizable(true)]
[HelpKeywordAttribute("AttributesDemoControlLibrary.AttributesDemoControl.TitleText")]
public string TitleText
{
    get
    {
        return this.label1.Text;
    }

    set
    {
        this.label1.Text = value;
    }
}

Atributo AmbientValue

O exemplo a seguir demonstra o AmbientValueAttribute e o código mostra que ofereça suporte a sua interação com o ambiente de design. Essa interação é chamada ambiência.

[AmbientValue(typeof(Color), "Empty")]
[Category("Appearance")]
[DefaultValue(typeof(Color), "White")]
[Description("The color used for painting alert text.")]
public Color AlertForeColor
{
    get
    {
        if (this.alertForeColorValue == Color.Empty &&
            this.Parent != null)
        {
            return Parent.ForeColor;
        }

        return this.alertForeColorValue;
    }

    set
    {
        this.alertForeColorValue = value;
    }
}

// This method is used by designers to enable resetting the
// property to its default value.
public void ResetAlertForeColor()
{
    this.AlertForeColor = AttributesDemoControl.defaultAlertForeColorValue;
}

// This method indicates to designers whether the property
// value is different from the ambient value, in which case
// the designer should persist the value.
private bool ShouldSerializeAlertForeColor()
{
    return (this.alertForeColorValue != AttributesDemoControl.ambientColorValue);
}

Atributos de vinculação de dados

Os exemplos a seguir demonstram uma implementação de vinculação de dados complexos.O nível de classe ComplexBindingPropertiesAttribute, mostrado anteriormente, especifica a DataSource e DataMember propriedades a ser usado para vinculação de dados. The AttributeProviderAttribute Especifica o tipo ao qual o DataSource propriedade se vinculará.

[Category("Data")]
[Description("Indicates the source of data for the control.")]
[RefreshProperties(RefreshProperties.Repaint)]
[AttributeProvider(typeof(IListSource))]
public object DataSource
{
    get
    {
        return this.dataGridView1.DataSource;
    }

    set
    {
        this.dataGridView1.DataSource = value;
    }
}
[Category("Data")]
[Description("Indicates a sub-list of the data source to show in the control.")]
public string DataMember
{
    get
    {
        return this.dataGridView1.DataMember;
    }

    set
    {
        this.dataGridView1.DataMember = value;
    }
}

Compilando o código

  • O formulário que hospeda o AttributesDemoControl requer uma referência para o AttributesDemoControl assembly para construir.

Consulte também

Tarefas

Como: Serializar coleções de tipos padrão com o DesignerSerializationVisibilityAttribute

Conceitos

Atributos de controles Windows Forms

Referência

IComparable

DataGridView

Outros recursos

Desenvolvimento personalizado de controles do Windows Forms com o .NET estrutura