Tips and Tricks
Contents
Flicker free drawing in controls
Embedding bitmaps in your manifest
Creating type safe Collections The quick way
Flicker free drawing in controls
Have just spent several days writing a beautiful looking custom control but are faced with one last problem this is SP Oiling the whole effect. Whenever the control is redrawn it flickers. This is most obvious then the control are being resized and so redrawn many times in succession.
Solving this problem are very easy with the. NET Framework. If you are come from a C + + and GDI background then the solution is to create a memory based, bitmap the control draw the Bitmap and then blit this to the screen (otherwise known as double buffering). This is such a common requirement that UserControl class actually implements this to you. All your need to does is include the following two lines of code into your class constructor.
The "The", "a", "double buffering be used whenever the Onbackground or OnPaint methods are. This would reduce then amount of flicker but may not remove it completely as painting the whole control still results in TW o Separate blitting operations.
The second line of code above are used to ensure this only a single blitting operation when occurs. This occurs the underlying Windows WM_PAINT message is processed. When this happens it would create the memory bitmap, call the Onbackground method, call the OnPaint method and then finally Blit then the screen.
The only drawback to this technique are the greater use of. However, most controls are relatively small in screens size and so are unlikely to being an issue.
Embedding bitmaps in your manifest
Usually a bitmap would be embedded to your assembly automatically, just by being associated and a property of a Form usi Ng the designer. But There are many circumstances where you are want to embed a bitmap (or other resource) without associating it and any Particular Form.
You can does this in Visual Studio. NET by right-clicking the project of interest and selecting the ' Add Existing Item ' Opti On. Navigate to your bitmap and selecting it'll make it appear in your project details. Now select the bitmap and modify "build" to become ' Embed as resource '. Rebuild your project and then use the ILDAsm.exe utility to examine the manifest of your for built. You'll now have the bitmap has been added as a resource.
To extract this resource the at runtime isn't obvious with only involves three steps.
Get the assembly we are built into
Assembly myassembly = assembly.getassembly (Type.GetType ("Mynamespace.thisclass"));
Get the resource stream containing the embedded resource
Stream ImageStream = Myassembly.getmanifestresourcestream ("Example.bmp");
Load the bitmap from the stream
Bitmap pics = new Bitmap (ImageStream);
The the ' The ' code is used to get a reference to the assembly this code is built into. In your own code your should substitute the ' Mynamespace.thisclass ' string for the fully qualified name of the class the CO De is inside.
The second line requests from the Assembly a stream that contains the contents of the named. This name would need to match the name of the appears when using the ILDAsm.exe utility. Visual Studio would create this name as the default namespace appended with the name of the file. If your code generates an exception on this point then double check the name of provide exactly matches that inside the M Anifest.
The last line of the code are obvious and simply uses the Bitmap constructor that takes as input a Stream.
If you are prefer to build your projects manually without Visual Studio then your can still use the same technique. Just use the/resource:example.bmp option into your CSC command to cause the bitmap to be embedded. In which, the name in the manifest would exactly match the resource filename rather than be modified by Visual Studio.
Creating type safe Collections The quick way
Often when writing your own class with need to expose a collection of items to the caller. Usually the caller would also need to modify this collection at runtime. For example, a TabControl has a collection of TabPage objects that the caller can modify to add and remove pages.
Although creating a collection class is isn't difficult it can be time consuming. Rather than begin from scratch it are much easier to derive from the framework class CollectionBase. This class would handle the management of the collection for us by using a ArrayList instance internally.
Two tasks however remain. The contents of the collection change of the "generate" and "so" our class can perform appropriate act ions. For example, where a new TabPage is added to a Pages collection The TabControl would need to be notified of it can Change the appearance appropriately. To achieve this we define a new class called collectionwithevents as shown below.
public class Collectionwithevents:collectionbase
{
Declare the event signatures
public delegate void Collectionclear ();
public delegate void CollectionChange (int index, object value);
Collection Change Events
public event Collectionclear clearing;
public event Collectionclear cleared;
public event CollectionChange inserting;
public event CollectionChange Inserted;
public event CollectionChange removing;
public event CollectionChange removed;
Overrides for generating events
protected override void OnClear ()
{
if (clearing!= null) clearing ();
}
Our second task are to ensure, the collection class is type specific. So we derive a type specific class from the Collectionwithevents base class and expose the set of methods the caller needs to manipulate it. For example, a collection to manipulate objects of type MyType would look like the following.
public class Mytypecollection:collectionwithevents
{
public int Add (MyType value)
{
Return base. List.add (value as Object);
}
public void Remove (MyType value)
{
Base. List.remove (value as Object);
}
public void Insert (int index, MyType value)
{
Base. List.insert (Index, value as Object);
}
public bool Contains (MyType value)
{
Return base. List.contains (value as Object);
}
Public MyType This[int Index]
{
get {return (base. List[index] as MyType); }
}
}
The advantage of this type is so any additional collections we need involve creating just a single class identical to The one above but with the MyType replaced with whichever new type we desire.
Using The collection is very simple. This is a example class, creates and exposes a collection for manipulation by the caller. The constructor hooks into some of the events it exposes in order to perform whatever implementation the actions are needs.
Class Example
{
protected Mytypecollection _collection;
Class Example ()
{
Create the new but empty collection
_collection = new Mytypecollection ();
Hookup to whichever events are of interest
_tabpages.cleared + = new Collectionwithevents.collectionclear (onclearedpages);
_tabpages.inserted + = new Collectionwithevents.collectionchange (oninsertedpage);
_tabpages.removed + = new Collectionwithevents.collectionchange (onremovedpage);
}
Public Mytypecollection Mytypes
{
get {return _collection;}
}
Public MyType This[int Index]
{
get {return _collection[index];}
}
protected void oninsertedpage (int index, object value)
{
MyType obj = value as MyType;
Todo...your actions
}
protected void onremovedpage (int index, object value)
{
MyType obj = value as MyType;
Todo...your actions
}
}
The above example only hooks into the events this occur after the collection has. In practice you'll probably also want to hook into those that occur before the collection is modified.
The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion;
products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the
content of the page makes you feel confusing, please write us an email, we will handle the problem
within 5 days after receiving your email.
If you find any instances of plagiarism from the community, please send an email to:
info-contact@alibabacloud.com
and provide relevant evidence. A staff member will contact you within 5 working days.