Q: Show a WinForms flash screen I need a certain time to start. I want to display a flash screen when the application continues to load (just like Visual Studio .NET and Office applications). There is no such control in the toolbox. How can I achieve it?
A: The code included in this column contains a splashscreen class:
Public Class Splashscreen
{
Public SplashScreen (Bitmap Splash);
Public void close ();
}
Splashscreen constructor can use the displayed bitmap as a parameter. Close method is used to close the flash screen. Typically, we use splashscreen in the method of processing form (FORM) (you can see the formed flash screen):
Private vid online (Object)
Sender, Eventargs E)
{
Bitmap SplashImage;
SplashImage = New
Bitmap ("splash.bmp");
Splashscreen splashscreen
Splashscreen = New
Splashscreen (SplashImage);
// Do some length Operations, Then:
Splashscreen.Close ();
Activate ();
}
After turning off the flash screen, you must activate the form and put it in the most prominent position.
You can use any bitmap as a flash screen. You can also create bitmaps from BMP or JPG files by building a new bitmap object:
Bitmap SplashImage;
SplashImage = New Bitmap ("splash.bmp");
Or you can also use a picture loaded from the form resource:
Using System.Resources;
Resourcemanager resources;
Resources = New
ResourceManager (TypeOf (MyForm);
Bitmap SplashImage;
SplashImage =
(Bitmap) (Resources.getObject)
SplashImage ")))
To achieve a flash point is not just what we see. It can rely on some good WinForms features, and it also involves some interesting design issues that are applied in other WinForms environments. The flash screen is actually a WinForms form called Splashform. You can take advantage of the changes you need through WinForms visual design window (Visual Designer) to convert a default form into a flash screen - this proves that WinForms is not only easy to use, but also a lot of functions. In this example, we add a separate control - a simple picture box called M_SPLashPictureBox.
When compiling, we don't know the size of the flash image because it is a runtime parameter, but the picture box needs to adjust the size according to the image. You can easily achieve this by setting the M_SPLashPictureBox's sizeMode property to AutoSize. Next, you must position the picture frame to the upper left corner of the form. You can implement it by setting the M_SPLashPictureBox's Dock property to Fill. This will fix the picture frame in the upper left corner. At runtime, it extends to the lower right corner to populate the form because the size mode is set to AutoSize. Finally, set the M_SPLashPictureBox's CURSOR property to AppStarting (with an hourglass with an indicator), if the user moves the mouse on the flash screen, he or she knows that the application is starting. figure 2.
Set visible properties for flash forms and picture boxes
The flash form should not display any control box buttons (close, minimize and maximize), and it will not have a title bar. We can set the SplashForm's ControlBox property to false via the visual design window; this cancels the control box (Control Box). You can clear the Text property in the design window to delete the title bar.
Let's take a look at the boundary of the flash screen. It should be a separate line - not the default adjustable boundary style - so we should set the form's FORMDERSTYLE attribute to fixedsingle. Set the topMost property to True so that the flash screen is always on the top of Z-Order (Windows in the order of the desktop display window). The flash screen should always be at the center of the screen. Fortunately, we can set the StartPosition property to CENTERSCREEN to implement this, WinForms will automatically consider the size of the window and place it. Figure 2 shows the Properties window of Splashform and M_SPlashPicturebox, summarizing the properties and new values you need to set.
Next, we need to write some code to adjust the size of the flash screen. Splashform constructor can use flashing pictures as a parameter and assign it to the picture of the picture box:
Internal Class Splashform: Form
{
PictureBox M_SplashPicturebox;
Public Splashform (Bitmap
SplashImage)
{
InitializationComponent ();
m_splashpicturebox.image =
SplashImage;
Clientsize =
m_splashpicturebox.size;
}
// REST of the IMPLEMENTATION
}
Note that you must set the SplashForm's client size to the size of the picture box, which will automatically adjust your size according to the size of the image. Result SplashForm can accurately display the picture in the picture box because the picture frame is placed in the upper left corner of the form.
You cannot display Splashform on the same thread used to load the application, because the thread is busy with the application without considering display or redrawing the flash screen. Alternatively, we should let SplashScreen create a working thread to display Splashform (see List 1). Work thread calls the Show method, this method creates a splashform object and calls its showdialog method:
Void show ()
{
m_splashform = new
Splashform (M_SPLASHIMAGE);
m_splashform.showdialog ();
}
ShowDialog Displays the form and starts popping the Windows message to the inside. The flash screen is running on its own thread, so the thread can perform message processing - not to point the primary application thread that loads the application. The next task is to find a method for the main application to turn off the flash screen. The easiest way is to use a signal notification to thread closing the form - unless the method of the thread is busy being filled in the form of the form (ShowDialog method), and cannot view the tag or event. The method of solving is simple, just use Windows Timers. Add a Timer Control to the form with a design window, set its interval property to an appropriate value, such as 500 milliseconds. The Timer class is actually based on the VM_TIMER message, so TIMER's Tick event is Windows message driver. The work thread provides that message to the flash screen, where it will view if you need to turn off the flash, because the primary application has completed loading. The SplashForm class provides the Boolean property hidesplash, the close method of SplashScreen set it to:
Public void close ()
{
M_SPlashForm.hidesplash = True;
M_Workerthread.join ();
}
HideSplash can access the M_Hidesplash Boolean member variable of Splashform. M_Hidesplash can be accessed by multiple threads, so HideSplash needs to access M_Hidesplash by locking SplashForm in a thread security method:
Public Bool Hidesplash
{
get
{
LOCK (this) {
Return M_Hidesplash;
}
}
set
{
LOCK (this) {
m_hiDesplash = value;
}
}
}
Splashform processes TIMER Tick events in the ONTICK method:
Private Void ONTICK (Object
Sender, Eventargs E)
{
IF (Hidesplash == True)
{
m_timer.enabled = false;
CLOSE ();
}
}
If the HideSplash property is set to True (because the splashscreen's Close method is called), ONTICK will make Timer invalid and turn off splashform. Its operation process is this: the main form starts load and displays the flash screen on another thread. The main form continues to start the application. Whether the flash screen regularly views (using Timer) should be closed. The Close method of SplashScreen is called when the main form is loaded. The Close method sets HideSplash to True and calls Join on the working thread, and the flash screen is turned off. This will hinder the display of the main form, so the main form is not displayed as long as the flash screen is displayed. When the next time Timer rang, it will view the value of HideSplash. It will cancel Timer and close Splashform because HideSplash is set to True. This will return the showdialog method (this method is called in the SPLASCREEN's Show method) and then returns show. Once returns show, the thread is terminated because the show is a thread method of the working thread. At this time, it will return Join in the Close method of SplashScreen. The Close method is returned to the main form, and the main form is now displayed.
Q: Allow sequentially, a serializable, a member of the NonSerializable, I have a sequentially-sequence class, which contains a database connection as a member variable. When I tried to serialize this class, an exception appeared because the connection was indisputable. If I labeled the connection to be inquirable, then I can serialize the class - but after the DeSerialization, I can't use this object because the connection member is invalid. What should I deal with? A: When you use the serializable property to identify a class for serialization, .NET believes that all member variables are also sequentially, if it finds an insequent member, it will thrown in serialization An exception in a serializationException type. However, the class may include a member that cannot be serialized. This type does not have a serializable attribute that cannot be serialized. Normally, this insequent member is a reference type and requires some special initial settings. To solve this problem, we need to identify such a member to be inquirable and use a customized step in the reverse sequence to initialize it.
You must use the nonserialized field attribute to identify members, allowing a sequentially-sequence type that contains an inquirable type as a member variable:
Public class myotherclass
{..}
[Serializable]
Public Class Myclass
{
[Nonserialized]
Myotherclass m_obj;
/ * Methods and Properties * /
}
When .NET serials a member variable, it will first check if there is a nonserialized property: if there is, .NET will ignore the variable, skip it. However, when the .NET is reverse selecinsized, it initializes the unsperformed member variable of the type, set it to the default value (for all reference types, the default is zero). Then, you will provide the code to initialize the variable to the correct value. Finally, the object must know when it is inseparable. You must implement the IDSerializationCallback interface, which is defined in system.Runtime.Serialization namespace:
Public Interface
IdeSerializationCallback
{
Void OnDeselIzation (Object
Sender);
}
After .NET completes the reverse selecente processing of the object, the IDSerializationCallback's ONDSerialization () method is called, allowing it to perform the required custom initialization steps. You can ignore the sending parameters because .net always set it to zero. The following code illustrates how to perform custom serialization by implementing IDSerializationCallback:
Using system.runtime.serialization;
[Serializable]
Public class myclass:
IdeSerializationCallback
{
[Nonserialized]
IDBCONNECTION M_CONNECTION;
Public void ONDSERIALIZATION (Object
Sender)
{
Debug.assert (m_connection ==
NULL);
M_Connection = newsqlConnection ();
m_connection.connectionstring =
"DATA
Source = ... ";
m_Connection.Open ();
}
/ * Other Members * /
}
In the code above, the MyClass class has a database connection as a member variable. SQLConnection is not a serialized type, so you need to identify it with a nonserialized property. Myclass creates a new connection object in its overdeeselization () implementation because the connection member is set to default (zero) after the connection member is default (zero). Then, by providing a connection string, myclass initializes a connection object and turns it.
About the Author:
Juval Lowy is an experienced software architect and is the person in charge of Idesign. This is a consultation and training company specializing in .NET design and .net transplantation. As a regional head of Microsoft in Silicon Valley, JuVal is responsible for helping to use .NET to enter into the enterprise. Recently, he wrote a name
Programming .Net Components (O'Reilly & Associates) book. You can pass
Www.ideesign.net contact him.