现在的位置: 首页 > 综合 > 正文

Walkthrough: Authoring a User Control with Visual C#

2011年05月25日 ⁄ 综合 ⁄ 共 15953字 ⁄ 字号 评论关闭
转:http://msdn2.microsoft.com/en-us/library/a6h7e207(vs.71).aspx
Walkthrough: Authoring a User Control with Visual C#

User controls provide a means by which custom graphical interfaces can be created and reused. A user control is essentially a component with a visual representation. As such, it might consist of one or more Windows Forms controls, components, or blocks of code that can extend functionality by validating user input, modifying display properties, or performing other tasks required by the author. User controls can be placed on Windows Forms in the same manner as other controls. In the first part of this walkthrough, you create a simple user control called ctlClock. In the second part of the walkthrough, you extend the functionality of ctlClock through inheritance.

Creating the Project

When you create a new project, you specify its name to set the root namespace, assembly name, and project name, and ensure that the default component will be in the correct namespace.

To create the ctlClockLib control library and the ctlClock control

  1. On the File menu, point to New and then select Project to open the New Project dialog box.
  2. Select the Windows Control Library project template from the list of C# Projects, and type ctlClockLib in the Name box.

    Note   The Windows Control Library template is not available in the Standard Edition of Visual C# .NET. For more information, see Visual C# Standard Edition Features.

    The project name, ctlClockLib, is also assigned to the root namespace by default. The root namespace is used to qualify the names of components in the assembly. For example, if two assemblies provide components named ctlClock, you can specify your ctlClock component using ctlClockLib.ctlClock. In Solution Explorer, right-click UserControl1 and select View Code from the shortcut menu.

  3. Locate the Class statement, public class UserControl1, and change UserControl1 to ctlClock to change the name of the component.

    Note   By default, a user control inherits from the UserControl class provided by the system. The UserControl class provides functionality required by all user controls, and implements standard methods and properties.

  4. Locate the constructor, public UserControl1(), and change UserControl1 to ctlClock.
  5. In Solution Explorer, click UserControl1, then in the Properties window, change the FileName property to ctlClock.cs.
  6. From the File menu, choose Save All to save the project.

Adding Windows Controls and Components to your User Control

A visual interface is an essential part of your user control. This visual interface is implemented by the addition of one or more Windows controls to the User Control Designer. In the following demonstration, you will incorporate Windows controls into your user control and write code to implement functionality.

To add a Label and a Timer to your user control

  1. In Solution Explorer, right-click ctlClock.cs, and then select View Designer.
  2. In the Toolbox, click the Windows Forms tab, and then double-click label.

    A label control named label1 is added to your control on the User Control Designer.

  3. In the designer, click label1. In the Properties window, set the following properties.
    Property Change to
    Name lblDisplay
    Text (blank space)
    TextAlign MiddleCenter
    Font.Size 14
  4. In the Toolbox, click Windows Forms, and then double-click Timer.

    Because a timer is a component, it has no visual representation at run time. It therefore does not appear with the controls on the User Control Designer, but rather in the component tray.

  5. In the component tray, click timer1 and set the Interval property to 1000, and the Enabled property to true.

    The Interval property controls the frequency with which the timer component ticks. Each time timer1 ticks, it runs the code in the timer1_Tick event. The interval represents the number of milliseconds between ticks.

  6. In the component tray, double-click timer1 to go to the timer1_Tick event for ctlClock.
  7. Modify the code so that it resembles the following code sample. Be sure to change the access modifier from private to protected:
    protected void timer1_Tick(object sender, System.EventArgs e)
        {
        // Causes the label to display the current time
        lblDisplay.Text = DateTime.Now.ToLongTimeString();
        }

    This code will cause the current time to be shown in lblDisplay. Because the interval of timer1 was set to 1000, this event will fire every thousand milliseconds, thus updating the current time every second.

  8. Modify the method to be overridable with the virtual keyword. For more information, see the next section of this topic, "Inheriting from a User Control".
    protected virtual void timer1_Tick(object sender, System.EventArgs e)

  9. From the File menu, choose Save All to save the project.

Adding Properties to Your User Control

Your clock control now encapsulates a Label control and a Timer component, each with its own set of inherent properties. While the individual properties of these controls will not be accessible to subsequent users of your control, you can create and expose custom properties by writing the appropriate blocks of code. In the following section, you will add properties to your control that enable the user to change the color of the background and text.

To add a Property to your user control

  1. In Solution Explorer, right-click ctlClock.cs, and then click View Code from the shortcut menu.

    The Code Editor for your control opens.

  2. Locate the public class ctlClock statement. Beneath the opening {, type:
    private Color colFColor;
        private Color colBColor;

    These statements create the private variables that you will use to store the values for the properties you are about to create.

  3. Type the following code beneath the variable declarations from step 2:
    // Declares the name and type of the property.
        public Color ClockBackColor
        // Retrieves the value of the private variable colBColor.
        {
        get
        {
        return colBColor;
        }
        // Stores the selected value in the private variable colBColor, and
        // updates the backcolor of the label control lblDisplay.
        set
        {
        colBColor = value;
        lblDisplay.BackColor = colBColor;
        }
        }
        // Provides a similar set of instructions for the forecolor.
        public Color ClockForeColor
        {
        get
        {
        return colFColor;
        }
        set
        {
        colFColor = value;
        lblDisplay.ForeColor = colFColor;
        }
        }

    The preceding code makes two custom properties, ClockForeColor and ClockBackColor, available to subsequent users of this control. The get and set statements provide for storage and retrieval of the property value, as well as code to implement functionality appropriate to the property.

  4. From the File menu, choose Save All to save the project.

Testing Your Control

Controls are not stand-alone applications; they must be hosted in a container. In order to test your control, you must provide a test project within which it runs. In this section, you will build your control and test it in a Windows Form.

To build your control

  • On the Build menu, click Build.

To create a test project

  1. On the File menu, point to Add Project and then click New Project to open the Add New Project window.
  2. Click Windows Application, and in the Name box, type Test.
  3. In Solution Explorer, right-click the References node for your test project. Click Add Reference to display the Add Reference dialog box.
  4. Click the tab labeled Projects. Your user control project will be listed under Project Name.
  5. Double-click your project.

    Note that your project now appears in the Selected Components window.

After you have added your reference, you can place your control in your form.

To test your control

  1. In the Toolbox, click My User Controls, and then scroll down until the control icon representing ctlClock is displayed.
  2. Double-click the ctlClock icon.

    A copy of your control is now added to your form. Note that it displays the current time and is updated each second.

  3. In the Toolbox, select the icon and move your mouse over your form.
  4. Hold down the left mouse button while moving the mouse across the form.

    Another copy of your control is drawn onto the form. You can add as many copies of your timer to your form as you want.

  5. In the designer, click one of the instances of ctlClock.

    The properties for this instance are displayed in the Properties window.

  6. In the Properties window, locate the ClockBackColor property, then select the property to display the color palette.
  7. Choose a color by clicking it.

    The background color of your control changes to the color you selected.

  8. Use a similar sequence of events to verify that the ClockForeColor property is functioning as expected.

In this section, you have seen how components and Windows controls can be combined with code and packaging to provide custom functionality in the form of a user control. You have learned to expose properties in your user control, and how to test your control after it is complete. In the next section you will learn how to construct an inherited user control using ctlClock as a base.

Inheriting from a User Control

In the previous section, you learned how to combine Windows controls, components, and code into reusable user controls. Your user control can now be used as a base upon which other controls can be built. The process of deriving a class from a base class is called inheritance. In this section, you will create a user control called ctlAlarmClock. This control will be derived from its parent control, ctlClock. You will learn to extend the functionality of ctlClock by overriding parent methods and adding new methods and properties.

Creating the Inherited Control

The first step in creating an inherited control is to derive it from its parent. This action creates a new control that has all of the properties, methods, and graphical characteristics of the parent control, but can also act as a base for the addition of new or modified functionality.

To create the inherited control

  1. In Solution Explorer, click ctlClockLib.
  2. From the Project menu, select Add Inherited Control.

    The Add New Item window opens with Inherited User Control selected.

  3. In the Name box, type ctlAlarmClock.cs, and click Open.

    The Inheritance Picker window appears.

  4. Under Component Name, double-click ctlClock.
  5. In Solution Explorer, browse the current projects. Note that a file called ctlAlarmClock has been added.

Adding the Alarm Properties

Properties are added to an inherited control in the same way they are added to a user control. You will now use the property declaration syntax to add two properties to your control: AlarmTime, which will store the value of the date and time the alarm is to go off, and AlarmSet, which will indicate whether or not the alarm is set.

To add Properties to your user control

  1. In Solution Explorer, right-click ctlAlarmClock and select View Code.
  2. Locate the public class statement. Note that your control inherits from ctlClockLib.ctlClock. Beneath the { statement, type the following code:
    private DateTime dteAlarmTime;
        private bool blnAlarmSet;
        // These properties will be declared as public to allow future
        // developers to access them.
        public DateTime AlarmTime
        {
        get
        {
        return dteAlarmTime;
        }
        set
        {
        dteAlarmTime = value;
        }
        }
        public bool AlarmSet
        {
        get
        {
        return blnAlarmSet;
        }
        set
        {
        blnAlarmSet = value;
        }
        }

Adding to the Graphical Interface of Your Control

Your inherited control has a visual interface that is identical to the control it inherits from. It possesses the same constituent controls as its parent control, but the properties of the constituent controls will not be available unless they were specifically exposed. You may add to the graphical interface of an inherited user control in the same manner as you would add to any user control. To continue adding to your alarm clock's visual interface, you will add a label control that will flash when the alarm is sounding.

To add the label control

  1. In Solution Explorer, right-click ctlAlarmClock and select View Designer from the shortcut menu.

    The designer for ctlAlarmClock opens in the main window.

  2. Click the display portion of the control, and observe the Properties window.

    Note that while all the properties are displayed, they are dimmed. This indicates that these properties are native to lblDisplay, and cannot be modified or accessed in the properties window. By default, controls contained in a user control are private, and their properties are not accessible by any means.

    Tip   If you want subsequent users of your user control to have access to its internal controls, declare them as public or protected. This will allow you to set and modify properties of controls contained within your user control by using the appropriate code.

  3. Add a Label control to your user control.
  4. Using the mouse, move the label control immediately beneath the display box. In the Properties window, set the following properties:
    Property Setting
    Name lblAlarm
    Text Alarm!
    TextAlign Middle Center
    Visible false

Adding the Alarm Functionality

In the previous sections, you added properties and a control that will enable alarm functionality in your user control. In this section, you will add code to compare the current time to the alarm time, and if they are the same, to flash an alarm. By overriding the timer1_Tick method of ctlClock, and adding additional code to it, you will extend the capability of ctlAlarmClock while retaining all of the inherent functionality of ctlClock.

To override the timer1_Tick method of ctlClock

  1. In the Code Editor, locate the private bool blnAlarmSet; statement. Immediately beneath it, add the following statement:

    private bool blnColorTicker;

  2. In the Code Editor, locate the } at the end of the class.
  3. Just before the }, add the following code:
    protected override void timer1_Tick(object sender, System.EventArgs e)
        {
        // Calls the Timer1_Tick method of ctlClock.
        base.timer1_Tick(sender, e);
        // Checks to see if the Alarm is set.
        if (AlarmSet == false)
        return;
        else
        // If the date, hour and minute of the alarm time are the same as
        // now, flash!
        {
        if (AlarmTime.Date == DateTime.Now.Date && AlarmTime.Hour ==
        DateTime.Now.Hour && AlarmTime.Minute == DateTime.Now.Minute)
        {
        // Makes lblAlarmVisible, and changes the backcolor based on
        // the value of blnColorTicker. The backcolor of the label
        // will flash once per tick of the clock.
        lblAlarm.Visible = true;
        if (blnColorTicker == false)
        {
        lblAlarm.BackColor = Color.Red;
        blnColorTicker = true;
        }
        else
        {
        lblAlarm.BackColor = Color.Blue;
        blnColorTicker = false;
        }
        }
        else
        {
        // Once the alarm has sounded for a minute, the label is made
        // invisible again.
        lblAlarm.Visible = false;
        }
        }
        }

The addition of this code accomplishes several tasks. The override statement directs the control to use this method in place of the method that was inherited from the base control. When this method is called, it calls the method it overrides by invoking the base.timer1_Tick statement, ensuring that all of the functionality incorporated in the original control is reproduced in this control. It then runs additional code to incorporate the alarm functionality. A flashing label control will appear when the alarm is triggered.

Your alarm clock control is almost complete. The only thing that remains is to implement a way to turn it off. To do this, we will add code to the lblAlarm_Click method.

To implement the shutoff method

  1. In Solution Explorer, right-click ctlAlarmClock.cs and click View Designer.

    The designer opens.

  2. Add a button to the control. Set the properties of the button as follows:
    Property Value
    Name btnAlarmOff
    Text Disable Alarm
  3. In the designer, double-click btnAlarmOff.

    The Code Editor opens to the private void btnAlarmOff_Click line.

  4. Modify this method so that it resembles the following:
    private void btnAlarmOff_Click(object sender, System.EventArgs e)
        {
        // Turns off the alarm
        AlarmSet = false;
        // Hides the flashing label
        lblAlarm.Visible = false;
        }

  5. From the File menu, choose Save All to save the project.

Testing Your Inherited Control

As with a standard user control, an inherited user control cannot stand alone and must be hosted in a form or other container. Since ctlAlarmClock has a greater depth of functionality, additional code is required to test it. In this section, you will write a simple program to test the functionality of ctlAlarmClock. You will write code to set and display the AlarmTime property of ctlAlarmClock, and will test its inherent functions.

To build and add your control to a test form

  1. In Solution Explorer, click ctlClockLib. On the Build menu, choose Build ctlClockLib.
  2. Add a new Windows Application project to the solution, and name it Test2.
  3. In Solution Explorer, right-click the References node for your test project. Click Add Reference to display the Add Reference window. Click the tab labeled Projects. Your project will be listed under Project Name. Double-click your project, and note that it now appears in the Selected Components window.
  4. In the Toolbox, click My User Controls.
  5. Scroll down until the icon for ctlAlarmClock comes into view.
  6. Double-click ctlAlarmClock to add a copy of ctlAlarmClock to your form.
  7. In the Toolbox, locate and double-click DateTimePicker to add a DateTimePicker control to your form, and add a Label control by double-clicking Label.
  8. Use the mouse to position the controls in a convenient place on the form.
  9. Set the properties of these controls as follows:
    Control Property Value
    label1 Text (leave blank)
      Name lblTest
    dateTimePicker1 Name dtpTest
      Format Time
  10. In the designer, double-click dtpTest.

    The Code Editor opens to private void dtpTest_ValueChanged.

  11. Modify the code so that it resembles the following:
    private void dtpTest_ValueChanged(object sender, System.EventArgs e)
        {
        ctlAlarmClock1.AlarmTime = dtpTest.Value;
        ctlAlarmClock1.AlarmSet = true;
        lblTest.Text = "Alarm Time is " +
        ctlAlarmClock1.AlarmTime.ToShortTimeString();
        }

  12. In Solution Explorer, right-click Test2 and choose Set as StartUp Project from the shortcut menu.
  13. From the Debug menu, choose Start.

    The test program starts. Note that the current time is updated in the ctlAlarmClock control, and that the starting time is shown in the DateTimePicker control.

  14. Click the DateTimePicker where the minutes of the hour are displayed.
  15. Using the keyboard, set a value for minutes that is one minute greater than the current time shown by ctlAlarmClock.

    The time for the alarm setting is shown in lblTest.

  16. Wait for the displayed time to reach the alarm setting time.

    When the displayed time reaches the time to which the alarm is set the lblAlarm will flash. Turn off the alarm by clicking btnAlarmOff. You may now reset the alarm.

This walkthrough has covered a number of key concepts. You have learned to create a user control by combining controls and components into a user control container. You have learned to add properties to your control, and to write code to implement custom functionality. In the second section, you learned to extend the functionality of a given user control through inheritence, and to alter the functionality of host methods by overriding those methods.

抱歉!评论已关闭.