Nowadays, it is a popular era of WPF. During this free time, I have also explored it. It is found that he and Win32 programming are very different. This article uses a stock check program to describe my initial understanding of WPF.
The program implements the following functions:
1. Use listview + gridview to display data (it is easy to use the DataGrid without feeling it is convenient)
2. Demonstrate the Data Binding Mechanism in WPF
3. multi-thread mode and multi-thread atomic synchronization in WPF are implemented.
4. Implemented the program Effect of pallets
Next let's take a look at the actual image effect:
You can customize the related stocks:
<? XML version = "1.0" encoding = "UTF-8"?>
<Configuration>
<Stocks>
<! -- Filtered stock information -->
<Add id = "500001" name = "Jintai fund"/>
<Add id = "002155" name = "Chenzhou mining"/>
<Add id = "600900" name = "Changjiang Electric Power"/>
<Add id = "000002" name = "Wanke a"/>
<Add id = "600036" name = "China Merchants Bank"/>
</Stocks>
<! -- Topmost or not -->
<Topmost> true </topmost>
<! -- Price of the data refresh time, in seconds -->
<Refreshperiodsecond> 150 </refreshperiodsecond>
<! -- Whether to enable the filter flag -->
<Filterenable> true </filterenable>
</Configuration>
Some code:
1. doevents implementation code:
Private Static dispatcheroperationcallback exitframecallback = new dispatcheroperationcallback (exitframe );
/// <Summary>
/// Processes all UI messages currently in the message queue.
/// </Summary>
Public static void doevents ()
{
// Create new nested message pump.
Dispatcherframe nestedframe = new dispatcherframe ();
// Dispatch a callback to the current message queue, when getting called,
// This callback will end the nested message loop.
// Note that the priority of this callback shocould be lower than the of UI event messages.
Dispatcheroperation exitoperation = dispatcher. currentdispatcher. begininvoke (dispatcherpriority. Background, exitframecallback, nestedframe );
// Pump the nested message loop, the nested message loop will
// Immediately process the messages left inside the message queue.
Dispatcher. pushframe (nestedframe );
// If the "exitframe" Callback doesn't get finished, abort it.
If (exitoperation. status! = Dispatcheroperationstatus. Completed)
{
Exitoperation. Abort ();
}
}
Private Static object exitframe (object state)
{
Dispatcherframe frame = state as dispatcherframe;
// Exit the nested message loop.
Frame. Continue = false;
Return NULL;
}
2. The code that the application runs only once:
Protected override void onstartup (startupeventargs E)
{
Process proc = process. getcurrentprocess ();
Process [] process = process. getprocessesbyname (Proc. processname );
If (process. length> 1)
{
Foreach (process PS in process)
{
If (PS. ID = Proc. ID)
{
Proc. Kill ();
Proc. waitforexit ();
Break;
}
}
}
Base. onstartup (E );
}
3. multi-thread asynchronous call:
Private void window_initialized (Object sender, eventargs E)
{
// Refresh the data according to the set time period refreshperiodsecond
Timer = new system. Threading. Timer (new system. Threading. timercallback (threadloadstockdata ),
This, timespan. Zero, timespan. fromseconds (dsecperiod ));
}
Public Delegate void methodhandler ();
Private Static void threadloadstockdata (Object window)
{
Winstockviewer wind = window as winstockviewer;
If (wind! = NULL)
{
// Obtain data Asynchronously
Wind. Dispatcher. begininvoke (New methodhandler (wind. loadstockdata ));
}
}
Public void loadstockdata ()
{
Try
{
Int nstock = stockconfig. Current. Stocks. count;
// Complete the first data request before the second request
While (listview1.items. Count <nstock & interlocked. compareexchange (ref winstockviewer. nthreadcount, 0, 0)> 0)
{
App. doevents ();
Thread. Sleep (20 );
}
String key = string. Format ("{0}", listview1.selectedvalue );
Listview1.itemssource = stockparser. getstocks (this );
This. Title = string. Format ("stock Viewer ({0})", listview1.items. Count );
If (! String. isnullorempty (key ))
{
Listview1.selectedvalue = key;
}
Listview1.updatelayout ();
This. cursor = cursors. Wait;
// Multi-thread synchronization, waiting for the required data to be prepared
While (listview1.items. Count <nstock & interlocked. compareexchange (ref winstockviewer. nthreadcount, 0, 0)> 0)
{
If (dkpanel. Visibility = visibility. Visible)
{
This. showloadingtext ();
}
App. doevents ();
Thread. Sleep (20 );
}
For (INT I = 0; I <= nstock-listview1.items. Count; I ++)
{
App. doevents ();
Thread. Sleep (nstock-listview1.items. Count) * 500 );
}
If (nstock> 0 & listview1.items. Count = nstock)
{
Interlocked. Exchange (ref winstockviewer. nthreadcount,-1 );
}
Dkpanel. Visibility = visibility. hidden;
This. cursor = NULL;
// Sort
If (_ lastheaderclicked! = NULL)
{
Routedeventargs evtargs = new routedeventargs (null, _ lastheaderclicked );
_ Lastdirection = listsortdirection. ascending? Listsortdirection. Descending: listsortdirection. ascending;
This. gridviewcolumnheader_clickedhandler (this, evtargs );
}
Else
{
Gridview GVW = listview1.view as gridview;
If (GVW! = NULL)
{
// Initialize the sorting
This. Sort (GVW. Columns [0]. headerstringformat, listsortdirection. ascending );
}
}
If (stockconfig. Current. topmost)
{
This. policyicon_doubleclick (this. policyicon, eventargs. Empty );
}
This. topmost = stockconfig. Current. topmost;
}
Catch (exception ex)
{
Throw ex;
}
}
Download program
: Http://download.csdn.net/source/1486692