Signal Strength Control in C#

來源:互聯網
上載者:User

本文轉自http://www.codeproject.com/KB/miscctrl/signalstrengthcontrol.aspx

 

 

  • Download source - 46.13 KB

 

Introduction

This is a relatively simple control that illustrates some of the techniques used in developing custom controls. We will look at the way we hide properties that we don't want exposed through the designer, correctly listing our custom properties, and some other pointers.

Background

Custom controls and design-time support are a little daunting, the MSDN documentation is difficult to wade through and unless we are shown how to do something, it isn't always apparent. I've been developing custom controls for a few years now and I'm still learning the intricacies of custom control development and rich design-time support. Hopefully this article will shed some light on the dark world of control development.

Hiding Properties

Before I really get into the meat of the SignalStrengthMeter, I want to delve into some control development subjects. The first of which is hiding properties at design time.

When you create a new custom control in Visual Studio, you inherit from the UserControl class most of the time. You can elect to inherit from just about any control, even things like Buttons, Panels, radio buttons, etc. It's best to pick a control that most closely represents the control that you want to develop. The problem is that whatever control you decide to inherit from, you are bound to have a bunch of properties in the window that don't do anything, or make no sense to what you are developing.

That's where property hiding comes in. Every property has a bunch of design time metadata associated with it, you just need to change the metadata so it doesn't show up in the properties window. The only way (that I've found at least) is to create a new "hiding" property and assign the proper metadata to it, like:

Collapse | Copy Code
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), EditorBrowsable(EditorBrowsableState.Never)]public new Image BackgroundImage{    get { return base.BackgroundImage; }    set { base.BackgroundImage = value; }} 

There are a couple interesting notes, the first is that the property has the keyword "new" in it before the type. This identifies to the compiler that you intend to "hide" the base type's implementation of that property (go ahead and remove it and try to compile, look at the error). Next are the Browsable and DesignerSerializationVisibility. Setting the Browsable attribute with the initializer false tells the Visual Studio designer that you don't want to show the property at design time. Setting the DesignerSerializationVisibility to "Hidden" tells the designer that you don't want to serialize (save) the settings of this property at design time.

Unfortunately this doesn't hide the property in code, it's still there bright as day. Even setting the access level to private or protected won't remove the member from code.

Describing Your Properties

This is one of the biggest problems you see with the homebrew controls you find in places like CodeProject, nobody takes the time to categorize or describe the controls so that you have a rich design time experience. Think of the poor developer that has to use your code!

There are 3 important settings to use when describing your data:

  • Browsable(true)
  • Category("Category Name")
  • Description("Description")

Obviously there are a lot more, but those are the basics. You might also want to look into using the DefaultValue property, which you can use to identify what the default is (so the value isn't Bolded in the properties window).

Here is an example of applying the three main attributes (and 2 others I'll describe below):

Collapse | Copy Code
[Browsable(true), EditorBrowsable( EditorBrowsableState.Always), Bindable( BindableSupport.Yes), Category("Appearance"), Description("Number of bars in the signal monitor")]public int NumberOfBars{    get { return numberOfBars; }    set { numberOfBars = value; this.Invalidate(); }}   

You can see that I applied the Browsable attribute so that it shows up in the properties window, the Category attribute to place the property in the Appearance category in the properties window, and Description so that when the user has the property selected, the description box at the bottom of the properties window shows a friendly description of the property.

I also used two other attributes I won't get into too much detail about, but you can set certain properties of your control to be "Advanced" properties, I always set this to always show, even though I can't find the place to hide advanced properties in Visual Studio. The second one describes the property as "bindable", meaning I'm allowing the application to bind to it for data driven applications (in my case I use them for skinning, but not in this project).

One last note about the Metadata; there is a metadata attribute called DisplayName, where you can set the name of the property to anything you want, so you can turn "NoSignalThreshold" into "No Signal Threshold". I would AVOID using this attribute. Why? Well if some developer down the line wants to extend your control, or base a new one off of your control, it makes it very difficult to hide the property if you have to search through Intellisense for it, when the actual property name doesn't match what is in the property window.

Custom Control Regions

I always hate the fact that setting a background as "transparent" really doesn't mean transparent, it just means it'll suck the background color off of its parent control (yes, a form is a control), and use that. I've written into this control the ability to set the control as truly transparent, by using a custom control region. You can take a look through the CalculateRegion() function to see how I've implemented it, but basically you just need to draw a GraphicsPath with the areas that you want, and leave everything else out.

This may have some performance implications since Windows now has to do some fancy clipping with complicated regions, but I think the visual payoff is worth it. The only problem is that if you set this control over another control (like a button), the user can click in between the regions and affect the control underneath it.

Using the Code

I'm not going to get into the implementation details heavily because there really isn't anything revolutionary about the code. It just draws a number of bars, calculating if they are filled or not, what the fill style is (Solid or Gradient), and what the color should be depending on the "quality" of the signal. Using the control is self explanatory, just drop the control on your form, set the MinValue and MaxValue properties, then set the value property.

You can set the orientation to be from right to left, left to right, top to bottom, and bottom to top. One thing I neglected to do was to make them top, bottom, left, or right justified, this is a possible future enhancement.

Points of Interest

UI development is a lot more art than skill, unfortunately I'm not very artful, there could be a lot of improvements to the look and feel of this control, go nuts!

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.