<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Dapfor.Net Grid Blog</title>
	<atom:link href="http://www.blog.dapfor.com/feed" rel="self" type="application/rss+xml" />
	<link>http://www.blog.dapfor.com</link>
	<description>.Net Grid and MFC Grid</description>
	<lastBuildDate>Tue, 18 Dec 2012 22:45:40 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>.NetGrid v2.8.5 has been released. New features and bug fixes</title>
		<link>http://www.blog.dapfor.com/netgrid-v2-8-5-has-been-released-new-features-and-bug-fixes</link>
		<comments>http://www.blog.dapfor.com/netgrid-v2-8-5-has-been-released-new-features-and-bug-fixes#comments</comments>
		<pubDate>Tue, 18 Dec 2012 22:45:40 +0000</pubDate>
		<dc:creator>dapadm</dc:creator>
				<category><![CDATA[basket viewer]]></category>
		<category><![CDATA[bug fixing]]></category>
		<category><![CDATA[new release]]></category>
		<category><![CDATA[.net]]></category>
		<category><![CDATA[.Net Grid features]]></category>
		<category><![CDATA[release]]></category>
		<category><![CDATA[threading]]></category>

		<guid isPermaLink="false">http://www.blog.dapfor.com/?p=205</guid>
		<description><![CDATA[The new version includes several bug fixes and new features added to Dapfor’s framework. The following features have been added: [NEW] added new DecimalFormat and a corresponding DecimalFormatAttribute for declarative formatting. public class Product { private decimal price; [DecimalFormat(Precision = 3, ShortForm = true, ShowZero = false)] public decimal Price { get { return price; [...]]]></description>
			<content:encoded><![CDATA[<div id="sectionSectionID0EVAAA">The new version includes several bug fixes and new features added to Dapfor’s framework. The following features have been added:</div>
<div id="sectionSectionID0EVAAA">
<ul>
<li>[NEW] added new <a href="http://doc.dapfor.com/net-suite/html/T_Dapfor_Net_Formats_DecimalFormat.htm">DecimalFormat</a> and a corresponding <a href="http://doc.dapfor.com/net-suite/html/T_Dapfor_Net_Formats_DecimalFormatAttribute.htm">DecimalFormatAttribute</a> for declarative formatting.
<div>
<pre>public class Product
{
    private decimal price;

    [DecimalFormat(Precision = 3, ShortForm = true, ShowZero = false)]
    public decimal Price
    {
        get { return price; }
    }
}</pre>
</div>
</li>
<li>[NEW] Added new <a href="http://doc.dapfor.com/net-suite/html/E_Dapfor_Net_Ui_Grid_FocusedColumnChanged.htm">Grid.FocusedColumnChanged</a> event.</li>
<li>[NEW] Added a section for <a href="http://www.dapfor.com/en/net-suite/net-grid/tutorial/appearance">grid painting system</a>.</li>
<li>[NEW] Added a section for <a href="http://www.dapfor.com/en/net-suite/net-grid/tutorial/cell-highlighting">cell highlighting system</a>.</li>
<li>[NEW] Added a new example that demonstrates design of <a href="http://www.dapfor.com/en/net-suite/net-grid/tutorial/basket-viewer">Backet component</a> that is used for measuring weight of financial instruments in the basket. Contains detailed explanation of main principles of developing high-performance application with intensive computing operations. Describes specifis of painting system in Windows OS.</li>
</ul>
<p>The following bugs have been fixed:</p>
<ul>
<li>[BUG] The standard editor drop-downs do not appear on the correct monitor, if the main monitor is the right monitor, and the editor is being hosted on a monitor to the left of it.</li>
<li>[BUG] The grid didn’t start editing data if nullable types existed.</li>
<li>[BUG] If <a href="http://doc.dapfor.com/net-suite/html/P_Dapfor_Net_Ui_Grid_DataObjects.htm">Grid.DataObjects</a> were used, the grid didn’t clear collection on calling <a href="http://doc.dapfor.com/net-suite/html/M_Dapfor_Net_Ui_RowCollection_Clear.htm">Grid.Rows.Clear()</a> method.</li>
<li>[BUG] Change of focused columns was displayed incorrectly in <strong>FocusMode.Cell</strong> focusing mode.</li>
<li>[BUG] The grid was hiding some rows when binding data in grid with existing grouping.</li>
<li>Minor bug fixes</li>
</ul>
<p>&nbsp;</p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.blog.dapfor.com/netgrid-v2-8-5-has-been-released-new-features-and-bug-fixes/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using Application.DoEvents() in real-time applications is dangerous!</title>
		<link>http://www.blog.dapfor.com/using-application-doevents-in-real-time-applications-is-dangerous</link>
		<comments>http://www.blog.dapfor.com/using-application-doevents-in-real-time-applications-is-dangerous#comments</comments>
		<pubDate>Tue, 06 Nov 2012 11:03:57 +0000</pubDate>
		<dc:creator>dapadm</dc:creator>
				<category><![CDATA[Performance]]></category>
		<category><![CDATA[.net]]></category>
		<category><![CDATA[CPU]]></category>
		<category><![CDATA[DoEvents]]></category>
		<category><![CDATA[performance]]></category>

		<guid isPermaLink="false">http://www.blog.dapfor.com/?p=192</guid>
		<description><![CDATA[It has been numerously written that Application.DoEvents() method is not desirable, especially for high-performance applications. There are many reasons for this starting from message processing procedure and ending with non-evident problems with application response  to user activity and code execution. In most cases programmers use this method without thinking of consequences or its working principle. [...]]]></description>
			<content:encoded><![CDATA[<p>It has been numerously written that<strong> Application.DoEvents()</strong> method is not desirable, especially for high-performance applications. There are many reasons for this starting from message processing procedure and ending with non-evident problems with application response  to user activity and code execution.</p>
<p>In most cases programmers use this method without thinking of consequences or its working principle. <a href="http://msdn.microsoft.com/en-us//library/system.windows.forms.application.doevents.aspx">MSDN documentation</a> says that this method processes messages in queue and when there are no more messages it stops working and passes control to the next code.<br />
In simplified form this method looks as follows:<br />
<code><br />
NativeUnsafeMethods.MSG msg;<br />
while (PeekMessage(out msg))<br />
{<br />
TranslateMessage(ref msg);<br />
DispatchMessage(ref msg);<br />
}</code></p>
<p>However, we may wonder what happens when application is intensively rendering controls, synchronizing threads and performing other operations in GUI thread? In such situation message queue always contains messages that don’t let method finish its work. As the result, the end user won’t notice the difference in application behavior as<strong> Application.DoEvents()</strong> will process executing messages, including WM_PAINT messages, i.e. controls will be redrawn and the program will not slow down. However, code execution will stop on <strong>Application.DoEvents()</strong> method. If there are important operations after this method, they will not be executed until message queue is freed. We have often seen the situation when application was updating stock market prices and in times of high volatility prices were updated with noticeable delays!!!</p>
<p>A simple example of the problem is shown below. Demo application intensively synchronizes threads and paints data. Main GUI thread continuously processes messages (including synchronization messages and WM_PAINT messages). Clicking Start button calls Application.DoEvents() once, and in normal situation it should immediately return control to subsequent code. However, in this example the things are different! This method is followed by MessageBox.Show(…) that doesn’t display anything.<br />
If demo application is fully covered with any other window or collapsed in the taskbar, Windows stops sending WM_PAINT messages and as the result of it message queue becomes empty, <strong>Application.DoEvents()</strong> method stops and MessageBox.Show(…) is executed.</p>
<p><a href="http://www.blog.dapfor.com/using-application-doevents-in-real-time-applications-is-dangerous/doevents" rel="attachment wp-att-194"><img class="size-full wp-image-194 alignleft" title="DoEvents" src="http://www.blog.dapfor.com/wp-content/uploads/2012/11/DoEvents.png" alt="" width="505" height="311" /></a></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>Download <a href="http://dapfor.com/downloads/net-suite-examples/DoEventsExample.zip">DoEventsExample.zip</a></p>
<p>Therefore, before using <strong>Application.DoEvents()</strong> programmers should look at application architecture and ask themselves whether this method is really necessary. If application code really requires <strong>Application.DoEvents()</strong>, we have added <strong>Dapfor.Net.Editors.MessageQueueHelper</strong> class starting from version 2.8.4. This class has similar behavior but it also supports maximum execution time limit. If there are no more messages in queue, <strong>MessageQueueHelper</strong> also stops and passes control to the subsequent code.</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.blog.dapfor.com/using-application-doevents-in-real-time-applications-is-dangerous/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>.NetGrid v2.8.4 has been released. Improvements when CPU is heavily loaded.</title>
		<link>http://www.blog.dapfor.com/netgrid-v2-8-4-has-been-released-improvements-when-cpu-is-heavily-loaded-2</link>
		<comments>http://www.blog.dapfor.com/netgrid-v2-8-4-has-been-released-improvements-when-cpu-is-heavily-loaded-2#comments</comments>
		<pubDate>Mon, 29 Oct 2012 22:59:48 +0000</pubDate>
		<dc:creator>dapadm</dc:creator>
				<category><![CDATA[bug fixing]]></category>
		<category><![CDATA[new release]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[CPU]]></category>
		<category><![CDATA[editing]]></category>
		<category><![CDATA[improvements]]></category>
		<category><![CDATA[performance]]></category>

		<guid isPermaLink="false">http://www.blog.dapfor.com/?p=187</guid>
		<description><![CDATA[This version contains bug fixes and performance improvements. The following features have been added: [NEW] Greatly improved the reliability and responsiveness of the grid when the CPU is heavily loaded. The following bugs have been fixed: [BUG] Fixed a bug in the column configurator which in some cases does not allow reordering of visible columns. [...]]]></description>
			<content:encoded><![CDATA[<p>This version contains bug fixes and performance improvements.</p>
<p>The following features have been added:</p>
<ul>
<li>[NEW] Greatly improved the reliability and responsiveness of the grid when the CPU is heavily loaded.</li>
</ul>
<p>The following bugs have been fixed:</p>
<ul>
<li>[BUG] Fixed a bug in the column configurator which in some cases does not allow reordering of visible columns.</li>
<li>[BUG] Fixed a bug where merged columns were drawn with artifacts.</li>
<li>[BUG] Fixed a bug when the grid incorrectly draws cells if there are simultaneously visible grouped rows and child header.</li>
<li>[BUG] Fixed a bug when the grid incorrectly displays a vertical scrollbar if there are simultaneously visible grouped rows and child header.</li>
<li>Minor bug fixes</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.blog.dapfor.com/netgrid-v2-8-4-has-been-released-improvements-when-cpu-is-heavily-loaded-2/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>.NetGrid v2.8.3 has been released. Column filters</title>
		<link>http://www.blog.dapfor.com/netgrid-v2-8-3-has-been-released-column-filters</link>
		<comments>http://www.blog.dapfor.com/netgrid-v2-8-3-has-been-released-column-filters#comments</comments>
		<pubDate>Thu, 13 Sep 2012 20:13:46 +0000</pubDate>
		<dc:creator>dapadm</dc:creator>
				<category><![CDATA[bug fixing]]></category>

		<guid isPermaLink="false">http://www.blog.dapfor.com/?p=180</guid>
		<description><![CDATA[This version contains minor bug fixes and some improvements. [BUG] Under certain conditions, the .Net Grid can draw artifacts in editable cells. [BUG] Fixed a bug where column filters do not work correctly on the second level of the hierarchy. [BUG] Fixed a bug where column filters are able to filter only string values. Minor [...]]]></description>
			<content:encoded><![CDATA[<p>This version contains minor bug fixes and some improvements.</p>
<ul>
<li>[BUG] Under certain conditions, the .Net Grid can draw artifacts in editable cells.</li>
</ul>
<ul>
<li>[BUG] Fixed a bug where column filters do not work correctly on the second level of the hierarchy.</li>
</ul>
<ul>
<li>[BUG] Fixed a bug where column filters are able to filter only string values.</li>
</ul>
<ul>
<li>Minor bug fixes</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.blog.dapfor.com/netgrid-v2-8-3-has-been-released-column-filters/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>.NetGrid v2.8.1 has been released. Hierarchical data relation</title>
		<link>http://www.blog.dapfor.com/netgrid-v2-8-1-has-been-released-hierarchical-data-relation</link>
		<comments>http://www.blog.dapfor.com/netgrid-v2-8-1-has-been-released-hierarchical-data-relation#comments</comments>
		<pubDate>Mon, 11 Jun 2012 21:19:52 +0000</pubDate>
		<dc:creator>dapadm</dc:creator>
				<category><![CDATA[Data binding]]></category>
		<category><![CDATA[new release]]></category>
		<category><![CDATA[binding]]></category>
		<category><![CDATA[datarelation]]></category>
		<category><![CDATA[dataset]]></category>
		<category><![CDATA[datatable]]></category>
		<category><![CDATA[hierarchy]]></category>
		<category><![CDATA[netgrid]]></category>

		<guid isPermaLink="false">http://www.blog.dapfor.com/?p=174</guid>
		<description><![CDATA[The main new feature in the version 2.8.1 is support for building a hierarchy of tables linked with DataRelation. &#160; New .Net Grid features: [NEW] Building hierarchy in a grid consisting of multiple tables using datarelation. The following bugs have been fixed: When a new theme was created basing on an existing theme, appearance data [...]]]></description>
			<content:encoded><![CDATA[<div>
<p>The main new feature in the version 2.8.1 is support for building a hierarchy of tables linked with DataRelation.</p>
<div>
<img class="alignnone" src="http://support.dapfor.com/attachments/token/91yl5jh3nikmqex/?name=hierarchical_datarelation.png" alt="hierarchical_datarelation.png" width="592" height="179" />
</div>
<p>&nbsp;</p>
<div>
New .Net Grid features:</p>
<ul>
<li>[NEW] <a href="http://doc.dapfor.com/net-suite/html/4377638f-95cb-4a4b-be3d-90ccb57232c6.htm">Building hierarchy in a grid</a> consisting of multiple tables using datarelation.</li>
</ul>
<p>The following bugs have been fixed:</p>
<ul>
<li>When a new theme was created basing on an existing theme, appearance data was not copied. This resulted in simultaneous appearance changes in both themes.</li>
<li>Minor bug fixes.</li>
</ul>
</div>
<p>&nbsp;</p>
<p>We hope that you will appreciate grid quality, performance and convenience of interface. Let’s create feature-rich high-performance applications together.</p>
<p>Sincererly Yours,</p>
<p>Dapfor</p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.blog.dapfor.com/netgrid-v2-8-1-has-been-released-hierarchical-data-relation/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>.Net performance. Practical recommendations</title>
		<link>http://www.blog.dapfor.com/net-performance-practical-recommendations</link>
		<comments>http://www.blog.dapfor.com/net-performance-practical-recommendations#comments</comments>
		<pubDate>Tue, 15 May 2012 21:07:42 +0000</pubDate>
		<dc:creator>dapadm</dc:creator>
				<category><![CDATA[Performance]]></category>
		<category><![CDATA[grid]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://www.blog.dapfor.com/?p=167</guid>
		<description><![CDATA[Even the best performing component can be hindered by incorrect use. Below we provide practical recommendations on what should be used or avoided in application programming. Following the tips below you will be able to create applications with the same efficiency as this demo application. We also provide source codes for this example to show [...]]]></description>
			<content:encoded><![CDATA[<div style="text-align: center; margin-bottom: 30px;"><img src="http://www.dapfor.com/images/ProductPicsImages/Performance.jpg" alt="" align="middle" /></div>
<p>Even the best performing component can be hindered by incorrect use. Below we provide practical recommendations on what should be used or avoided in application programming. Following the tips below you will be able to create applications with the same<br />
efficiency as <a href="http://www.dapfor.com/downloads/net-suite-examples/Dapfor.Grid.PerfDemo.zip" target="_blank">this demo application</a>. We also provide <a href="http://www.dapfor.com/downloads/net-suite-examples/Dapfor.Grid.PerfDemo_src.zip" target="_blank">source codes</a> for this example to show how easy it is.</p>
<ul>
<li>It is supposed that programmers already know general principles of application design. Nevertheless, we shall provide  some useful links for better understanding of .Net environment and tools for writing managed code: <a href="http://msdn.microsoft.com/en-us/library/ms973852" target="_blank">Writing Faster Managed Code: Know What Things Cost</a></li>
<li>It is necessary to pay attention to <a href="http://www.dapfor.com/en/net-suite/net-grid/features/performance">grid characteristics</a> in different working modes, to evaluate data volume to be  displayed and to find a relevant chart for better understanding of grid use.</li>
<li>Use ThreadSafeBindingList&lt;T&gt; instead of BindingList&lt;T&gt; for the following reasons:1. BindingList&lt;T&gt; has poor implementation when working with objects that implement INotifyPropertyChanged interface.  <a href="http://www.dapfort.com/en/net-suite/net-grid/tutorial/threadsafe-bindinglist">Here</a>you can find more information on BindingList&lt;T&gt; performance issues.  Use ThreadSafeBindingList&lt;T&gt; instead, as it doesn’t allow BindingList&lt;T&gt; to subscribe to events of objects that it contains.2. Another reason to use ThreadSafeBindingList&lt;T&gt; instead of BindingList&lt;T&gt; is related to implementation of  MulticastDelegate used in events. With one subscriber, this delegate consumes minimum memory resources, but when there are two  or more subscribers, it creates an internal subscriber collection that increases memory consumption dramatically. The grid always subscribes  to objects that implement INotifyPropertyChanged interface and BindingList&lt;T&gt; is the second subscriber.</li>
<li>If BindingList&lt;T&gt; is used together with objects implementing INotifyPropertyChanged interface, it is  better to avoid firing notifications with non-existent data object properties. It is mainly required because when a binding  list receives such notification it checks whether the firing object has the specified property. If the firing object doesn’t  have such property, the BindingList&lt;T&gt; generates <strong>ListChanged</strong> event specifying <strong>Reset</strong> reason and forcing the grid to rebuild all its contents.</li>
<li>Avoid using INotifyPropertyChanged interface, unless it is required. If the object doesn’t change at run-time, it is better not to use this interface to save memory and CPU resources.</li>
<li>Add data to the end of collection (List&lt;T&gt;, BindingList&lt;T&gt;, ThreadSafeBindingList&lt;T&gt; etc). Otherwise, internal implementation of indexed collections will move and re-index all data starting from the newly added index.</li>
<li>Avoid adding data to a binding list with more than 10 000 items when the grid is sorted. Stop sorting to improve performance.  However, if you need to add large amounts of data in real-time to the beginning of the grid, it&#8217;s better to use the following:
<div>
<pre>grid.Sort.Enabled = false;
grid.DataSource = _datasource_;</pre>
<pre>//Add a single object to the beginning of the grid
grid.Nodes.Insert(0, _new_object_);

//Add a single object to the beginning of the binding list
IBindingList bl = ...;
bl.Insert(0, _new_object_);</pre>
</div>
</li>
<li>Although the grid is thread-safe with INotifyPropertyChanged and IBindingList interfaces, use the GUI thread  to work with it. This is mainly important for adding large data volumes. Some optimization algorithms work better when there  is no need to switch between threads. Please also note that BindingList&lt;T&gt; is not thread-safe.</li>
<li>Have only one message loop per application. Don&#8217;t create grids in different threads.Let us assume that the computer resources are not limitless. Theoretically the maximum performance can be obtained  if the number of threads equals to the number of processor cores. While a lot of threads are creating, they aren’t working in parallel.  In this case cores allocate time slices to threads based on their priority and consistently perform context switches (context switch is relatively expansive operation). Note, maximum time slice is about 10-15 msec.We have also take into account that each control paints its content in the GDI/GDI+ device (via the Graphics object).  While painting from one thread all others wait for GDI device to perform painting in its turn. Therefore if we start many  message loops – it doesn’t mean that we accelerate the application. In other words the application losses time on context  switches and on drawing in GDI device.
<p>From our point of view the application should have only one message pump. Windows has additional mechanisms  to optimize content drawing and we are not sure that they work in case of multithreaded environment. Of course,  business logic can work in any thread, but the graphical thread should be only one in the application.</li>
<li>Use MethodInvoker to synchronize threads.In multi-threaded applications every call should be synchronized with the main thread containing windows message loop. Both <strong>Control.Invoke</strong> and <strong>Control.BeginInvoke</strong>methods may accept  different delegate types and their parameters. However, this causes a serious performance issue as they call  Delegate.DynamicInvoke(params object[] args), which in turn uses low-performance reflection. At the same time, for some delegates such as EventHandler, MethodInvoker and WaitCallback the code is called directly.  In the time of code execution the delegate is checked for belonging to one of the above types with specified number of parameters, and if it doesn’t – DynamicInvoke() is called.From practical point of view the synchronization process should look as follows:
<div>
<pre>someControl.BeginInvoke(new MethodInvoker(delegate
{
    //a code here
}));</pre>
</div>
</li>
<li>Use objects of arbitrary classes instead of collections of values of string[] type, etc. It is more convenient and objects of arbitrary classes consume less memory than string collections.</li>
<li>Don’t format values directly in data objects, i.e. if an object property is to return date, this field should return DateTime object type instead of string type. Use <a href="http://www.dapfort.com/en/net-suite/net-grid/tutorial/data-formatting">data formatting</a> if needed. If properties return strings, they can be <a href="http://www.dapfort.com/en/net-suite/net-grid/tutorial/data-sorting">compared incorrectly</a>during data sorting. Besides, comparing two strings requires more CPU resources than comparing two DateTime objects.
<div>
<pre>class DateExample
{
    ...

    //Bad idea
    public string FormattedDate
    {
        get { return string.Format("{0:yyyy-MM-dd}", _date); }
    }

    //Good idea: the property should return non-formatted value
    [Format("yyyy-MM-dd")]
    public DateTime Date
    {
        get { return _date; }
    }
}</pre>
</div>
</li>
<li>Use the <a href="http://www.dapfort.com/en/net-suite/net-grid/tutorial/event-driven-model">event-driven model</a>, if possible. On global scale it is more efficient than searching for rows in one or more grids with dynamically changing data.</li>
<li>Share the same business objects in different grids.  Use <a href="http://www.dapfort.com/en/net-suite/net-grid/tutorial/data-binding">declarative binding</a>. This simplifies the application code and significantly reduces memory consumption.</li>
<li>Avoid using unnecessary wrappers. Use declarative binding instead of <a href="http://www.dapfor.com/en/net-suite/net-grid/features/composite-objects">creating intermediate classes</a>.</li>
<li>Use statically declared EventArgs for data fields to avoid creating numerous short-lived objects when sending notifications via INotifyPropertyChanged interface.
<div>
<pre>class MyDataObject : INotifyPropertyChanged
{
    private static readonly PropertyChangedEventArgs Value1Args = new PropertyChangedEventArgs("Value1");

    private string _value1;

    public string Value1
    {
        get { return _value1; }
        set
        {
            if (_value1 != value)
            {
                _value1 = value;

                //Bad idea: short-lived object is created
                FirePropertyChanged("Value1");

                //Good idea: notify with an immutable static object
                FirePropertyChanged(Value1Args);
            }
        }
    }

    private void FirePropertyChanged(string fieldName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(fieldName));
        }
    }

    private void FirePropertyChanged(PropertyChangedEventArgs args)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, args);
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
}</pre>
</div>
</li>
<li>Work with business logic objects directly instead of calling Cell.Value/Row.DataAccessor["fieldId"].ValueTypeDescriptor/PropertyDescriptor are used to display values in cells when working with arbitrary data types.<br />
The following code demonstrates value extraction from data objects.</p>
<div>
<pre>MyDataObject dataObject = ...;
dataObject.Value1 = "some value";

PropertyDescriptor property = TypeDescriptor.GetProperties(dataObject)["Value1"];
object value = property.GetValue(dataObject);</pre>
</div>
<p>This working principle is the same for all grids of all vendors. The main issue is that PropertyDescriptor.GetValue() method uses reflection. NetGrid has an optimization that enables it to receive notifications from INotifyPropertyChanged/IBindingList without calling data object getters. Values are required only at the time of painting and only for visible cells. If the grid has a lot of rows, most of them are invisible and this approach significantly saves CPU resources. It is worth considering in application development. As an example, let’s review subscription to Grid.RowUpdated event:</p>
<div>
<pre>grid.RowUpdated += delegate(object sender, GridRowUpdateEventArgs e)
{
    //This callback is called each time when a notification from INotifyPropertyChanged received.

    //Using of custom object will reduce CPU consumption
    MyDataObject myObject = (MyDataObject) e.Row.DataObject;
    decimal lastPrice = myObject.LastPrice;

    //The following call will use the reflection. Try to avoid.
    lastPrice = (decimal) e.DataField.Value;
};</pre>
</div>
</li>
<li>Use new Row.IsInVisibleBounds property added to version 2.8.0.When updating data in real time in applications, the grid stores highlighting information for each updated cell. This default behavior causes serious consumption of memory resources in addition to CPU resource consumption  due to processing large volume of information. As most updates can occur outside the visible area, the programmer can save CPU resources by using the new property.
<div>
<pre>//Disable authomatic highlighting (from INotifyPropertyChnaged interface)
grid.Highlighting.Enabled = false;

//This callback is called each time when a notification from INotifyProeprtyChanged received.
grid.RowUpdated += delegate(object sender, GridRowUpdateEventArgs e)
{
    //Handle updates only for visible rows
    if(e.Row.IsInVisibleBounds)
    {
        //Using of custom object will reduce CPU consumption
        MyDataObject myObject = (MyDataObject)e.Row.DataObject;
        double delta = myObject.LastPrice - myObject.PrevPrice;
        if(delta != 0)
        {
            Color color = delta &gt; 0 ? Color.Green : Color.Red;
            //highlight the 'LastPrice' cell with specified semi-transparent color for 2 seconds
            e.Row["LastPrice"].Highlight(TimeSpan.FromSeconds(2), Color.FromArgb(50, color));
        }
    }
};</pre>
</div>
<p>When this optimization is used, vertical scrolling may bring rows without cell highlighting information to the visible area and the user will not see cell highlights that were made before rows get to visible area of the grid. This concerns only highlighting information, while text and other cell content will display correctly. The programmer should decide whether to use such optimization or not.</li>
<li>While construction of the hierarchy is preferable to collapse root rows:
<div>
<pre>grid.RowAdded += delegate(object sender, GridRowEventArgs e)
{
    e.Row.Expanded = false;
};</pre>
</div>
</li>
<li>Turn off fading effect when building real-time applications:
<div>
<pre>grid.Highlighting.Fading = false;</pre>
</div>
</li>
<li>Avoid settins colors, fonts in rows and cells because of high memory consumption (Colors and fonts are stored per cell or row). Use <strong>Grid.Appearance / Header.Appearence</strong> properties  and <strong>Grid.PaintRow / Grid.PaintCell</strong>event handlers instead:
<div>
<pre>//The back color is stored per cell. If grid has thousands rows, memory consumption can be very high.
Cell cell = grid.Rows[0]["Price"];
cell.Appearance.BackColor = Color.Red;

//The back color is stored per row. If grid has thousands rows, memory consumption can be very high.
Row row = grid.Rows[0];
row.Appearance.BackColor = Color.Blue;

//Good idea: colors are stored per grid
grid.Appearance.EvenRows.BackColor = Color.FromArgb(10, Color.Red);
grid.Appearance.OddRows.BackColor = Color.FromArgb(10, Color.Blue);

//Good idea: colors are stored per header (therefore per hierarchical level)
Header header = grid.Headers[0];
header.Appearance.EvenRows.BackColor = Color.FromArgb(10, Color.Red);
header.Appearance.OddRows.BackColor = Color.FromArgb(10, Color.Blue);

//Good idea: colors are specified only at painting time
grid.PaintRow += delegate(object sender, PaintRowEventArgs e)
{
    e.Appearance.BackColor = e.Row.VisibleIndex % 2 == 0
                                 ? Color.FromArgb(10, Color.Red)
                                 : Color.FromArgb(10, Color.Blue);
};</pre>
</div>
</li>
<li>Try avoiding reflection.</li>
<li>Be very careful about creating temporary objects as it may result in memory pressure and make garbage  collector collect unused objects more frequently. Please note that when garbage is collected, all application threads  are temporarily stopped.</li>
<li>Don’t use finalizers in objects unless necessary.</li>
</ul>
<p>We hope that these simple recommendations will help you create efficient and high-performing applications.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.blog.dapfor.com/net-performance-practical-recommendations/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>.NetGrid v2.8.0 has been released. RTL support, performance improvements</title>
		<link>http://www.blog.dapfor.com/netgrid-v2-8-0-has-been-released-rtl-support-performance-improvements</link>
		<comments>http://www.blog.dapfor.com/netgrid-v2-8-0-has-been-released-rtl-support-performance-improvements#comments</comments>
		<pubDate>Mon, 14 May 2012 21:21:54 +0000</pubDate>
		<dc:creator>dapadm</dc:creator>
				<category><![CDATA[new release]]></category>
		<category><![CDATA[grid]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[release]]></category>
		<category><![CDATA[RTL]]></category>

		<guid isPermaLink="false">http://www.blog.dapfor.com/?p=160</guid>
		<description><![CDATA[We are happy to announce that a new grid version is out. The version 2.8.0 of .Net Grid has a lot of new performance improvements and new features. Performance improvements Significantly improved BindingList performance, especially with objects implementing INotifyPropertyChanged interface. Here you may learn about causes of poor performance and methods for performance improvement. Significantly [...]]]></description>
			<content:encoded><![CDATA[<div>
<p>We are happy to announce that a new grid version is out. The version 2.8.0 of .Net Grid has a lot of new performance improvements and new features.</p>
<h3>Performance improvements</h3>
<ul>
<li>Significantly improved BindingList performance, especially with objects implementing INotifyPropertyChanged interface. <a href="http://www.dapfor.com/en/net-suite/net-grid/tutorial/threadsafe-bindinglist">Here </a>you may learn about causes of poor performance and methods for performance improvement.</li>
</ul>
<ul>
<li>Significantly improved disposing performance for grids with a large number of sorted cells.</li>
</ul>
<ul>
<li>Optimized real-time cell highlighting.</li>
</ul>
<ul>
<li>Added new tutorials with <a href="http://www.dapfor.com/en/net-suite/net-grid/tutorial/performance-practical-recommendations">practical guidelines</a> on grid usage. The <a href="http://www.dapfor.com/downloads/net-suite-examples/Dapfor.Grid.PerfDemo.zip">provided example</a> shows impressive performance that can be achieved by following these simple guidelines.</li>
<li>Significantly increased binding speed of sorted grid</li>
</ul>
<h3>New features</h3>
<ul>
<li>RTL support (in the grid, editors, context menus, tooltips, reporting).</li>
<li>Added support of merged columns for combining columns in groups with common header. Within these groups users may move columns, change column size and run sorting. Full customization of header appearance is supported including insertion of images, changing background color or fonts.
<div><img src="http://support.dapfor.com/attachments/token/sk4443qybxf2dxp/?name=merged_columns.png" alt="merged_columns.png" /></div>
</li>
<li>Added <strong>Grid.Nodes.Insert()</strong> method enabling inserting data, not only at the end of the grid, but also in any position.</li>
<li>Added <strong>Row.Insert()</strong> method enabling inserting data at any hierarchical level in any position.</li>
<li>Foreground color blinking: <strong>Cell.Highlight(TimeSpan interval, Color backColor, Color foreColor)</strong> method was added.</li>
<li>Public toolstrip items <strong>ToolStripGridColumn</strong>, <strong>ToolStripGridGroupBoxPanel</strong>, <strong>ToolStripGridHeaderConfigurator</strong> and <strong>ToolStripGridRemoveSort</strong> were added. Now a programmer can subscribe to <strong>Grid.HeaderContextMenu.ItemClicked</strong> event and get information of header and column where the click was made.</li>
<li>Drag&amp;drop support in grouped rows</li>
<li>Added AllowNew, AllowRemove, AllowEdit setters in <strong>ThreadSafeBindingList&lt;T&gt;</strong></li>
<li>Possibility of using <strong>IFormat</strong> objects in unbound columns was added.</li>
<li>Removing highlighting of entire row upon receiving notification from <strong>INotifyPropertyChanged</strong> with non-existent field.</li>
<li>Support of themes in column filters</li>
<li>Many other improvements (see full list <a href="http://www.dapfor.com/en/net-suite/net-grid/release-notes">here</a>).</li>
</ul>
<p>&nbsp;</p>
<p>Dapfor’s developers continuously strive to improve .NetGrid performance and to add new grid features making it easier for developers to use and greatly increasing performance of grid-based applications. A convenient API makes cell highlighting and simultaneous data filtering, sorting and grouping with highest performance really trivial tasks. Any hierarchy can be created easily. Dapfor is the only grid vendor enabling use of <a href="http://www.dapfor.com/en/net-suite/net-grid/tutorial/event-driven-model">thread-safe event driven model</a> in the application.</p>
<p>We hope that you will appreciate grid quality, performance and convenience of interface. Let’s create feature-rich high-performance applications together.</p>
<p>&nbsp;</p>
<p>Sincererly Yours,</p>
<p>Dapfor</p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.blog.dapfor.com/netgrid-v2-8-0-has-been-released-rtl-support-performance-improvements/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Why BindingList is slow with objects implementing INotifyPropertyChanged interface</title>
		<link>http://www.blog.dapfor.com/why-bindinglist-is-slow-with-objects-implementing-inotifypropertychanged-interface</link>
		<comments>http://www.blog.dapfor.com/why-bindinglist-is-slow-with-objects-implementing-inotifypropertychanged-interface#comments</comments>
		<pubDate>Thu, 29 Mar 2012 18:59:31 +0000</pubDate>
		<dc:creator>dapadm</dc:creator>
				<category><![CDATA[Data binding]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[BindingList]]></category>
		<category><![CDATA[INotifyPropertyChanged]]></category>
		<category><![CDATA[performance]]></category>

		<guid isPermaLink="false">http://www.blog.dapfor.com/?p=139</guid>
		<description><![CDATA[A BindingList&#60;T&#62; is the main tool for binding objects to grids. It is a container that may notify subscribers when data is added or removed. For this purpose it provides public ListChanged event that specifies collection changes with ListChangedType. Besides changing the collection itself (adding, removing, etc) the binding list notifies of data object changes. [...]]]></description>
			<content:encoded><![CDATA[<p>A <strong>BindingList&lt;T&gt;</strong> is the main tool for binding objects to grids. It is a container that may notify subscribers when data is added or removed. For this purpose it provides public ListChanged event that specifies collection changes with ListChangedType. Besides changing the collection itself (adding, removing, etc) the binding list notifies of data object changes. In other words, when data is added to collection <strong>BindingList&lt;T&gt;</strong> checks whether it implements <strong>INotifyPropertyChanged</strong> interface. If it is implemented, the collection subscribes to each object changes and forwards notifications as <strong>IBindingList.ListChanged</strong> events with <strong>ListChangedType.ItemChanged</strong> type and with specified PropertyDescriptor that is searched by reflection. </p>
<p>It’s worth mentioning that handler of <strong>INotifyPropertyChanged</strong> notification is very poorly implemented. Low performance reflection is used for searching PropertyDescriptor and internal cache is very poorly organized thus significantly reducing performance. Specifically when the <strong>BindingList&lt;T&gt;</strong> receives notifications of new object, it compares this object with the previous object that was used for notification. If they are not identical, the binding list does a terrible thing – it runs through all objects to get the index of the notifying object. This seriously impacts performance when there are a lot of elements. When the number of elements is about 100 000, handling of a single notification takes about 1 ms, which is unacceptable for most applications. </p>
<p>In actual applications <strong>ListChangedType.ItemChanged</strong> event with <strong>ListChangedType.ItemChanged</strong> flag and set PropertyDescriptor is handled quite rarely. However, it is hard to disable <strong>INotifyPropertyChanged</strong> handling in a <strong>BindingList&lt;T&gt;</strong> via simple means. The only acceptable method of disabling handling is to use reflection. The thing is that the binding list in its constructor checks whether the data type implements <strong>INotifyPropertyChanged</strong> interface and sets <strong>raiseItemChangedEvents</strong> private variable to true if it does. Otherwise it is set to false. This variable influences only subscriptions to <strong>INotifyPropertyChanged</strong> interface. There is no direct access to this variable and it can be modified only via reflection. An example of code for this is provided below. </p>
<pre>
class CustomBindingList&lt;T&gt; : BindingList&lt;T&gt;
{
    public CustomBindingList()
    {
        FieldInfo fi = typeof (BindingList&lt;T&gt;).GetField("raiseItemChangedEvents",
                               BindingFlags.Instance | BindingFlags.NonPublic);
        if (fi != null)
        {
            fi.SetValue(this, false);
        }
    }
}
</pre>
<p><br/></p>
<p>The above implements fully functional binding list with disabled handling of <strong>INotifуPropertyChanged</strong> interface events. At the same time the binding list notifies subscribers of adding or removing data just like in standard implementation of this container. </p>
<p>Some figures: In standard binding list implementation handling of 1000 notifications in 100 000 container took more than 600 msec. In optimized version this time – 0 since the container no longer subscribes to data objects. Besides that, no subscription enables memory saving. </p>
<p>This article concerns only binding list performance aspects. Another important aspect of working with binding lists <strong>INotifyPropertyChanged</strong> is their use in <a href="http://www.dapfor.com/en/net-suite/net-grid/tutorial/data-binding">advanced binding</a>.  </p>
]]></content:encoded>
			<wfw:commentRss>http://www.blog.dapfor.com/why-bindinglist-is-slow-with-objects-implementing-inotifypropertychanged-interface/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>.NetGrid 2.7.0 has been released. New reporting features</title>
		<link>http://www.blog.dapfor.com/netgrid-2-7-0-released-reporting-features</link>
		<comments>http://www.blog.dapfor.com/netgrid-2-7-0-released-reporting-features#comments</comments>
		<pubDate>Sun, 19 Feb 2012 20:22:34 +0000</pubDate>
		<dc:creator>dapadm</dc:creator>
				<category><![CDATA[new release]]></category>
		<category><![CDATA[.Net Grid features]]></category>
		<category><![CDATA[printing]]></category>
		<category><![CDATA[release]]></category>
		<category><![CDATA[reporting]]></category>

		<guid isPermaLink="false">http://www.blog.dapfor.com/?p=113</guid>
		<description><![CDATA[We have released a new version of .Net Grid! This version contains new reporting features and bug fixes. .Net Suite, v2.7.0 (Build 2.7.0.46034) [2012-02-20] Starting from version 2.7.0 grid functionality has been expanded with reporting and printing features. Programmers get simple and convenient interface for implementing new features and can significantly expand capabilities of target [...]]]></description>
			<content:encoded><![CDATA[<p>We have released a new version of .Net Grid!  This version contains new reporting features and bug fixes.</p>
<p><strong>.Net Suite, v2.7.0 (Build 2.7.0.46034) [2012-02-20]</strong></p>
<p>Starting from version 2.7.0 grid functionality has been expanded with <a href="http://www.dapfor.com/en/net-suite/net-grid/features/reporting">reporting and printing features</a>. Programmers get simple and convenient interface for implementing new features and can significantly expand capabilities of target applications.</p>
<table>
<tr>
<td>
<a href="http://www.blog.dapfor.com/netgrid-2-7-0-released-reporting-features/print_preview" rel="attachment wp-att-114"><img src="http://www.blog.dapfor.com/wp-content/uploads/2012/02/print_preview.png" alt=".Net Grid reporting features" title="print_preview" width="375" height="554" class="aligncenter size-full wp-image-114" /></a>
</td>
</tr>
</table>
<p><br/><br />
<strong>Reporting features:</strong></p>
<ul>
<li>Software control of reporting with full customization support.</li>
<li>Possibility of adding any images or text to printed pages.</li>
<li>Page spanning: If there are too many fields to fit on one page, the fields can span two or more pages.</li>
<li>Repeating headers: to improve document readability the grid can insert headers to every printed page.</li>
<li>Reports for top-level headers and child headers with relevant content.</li>
<li>Hiding headers in reports</li>
<li>Repeating selectors: if content has many columns, the grid can span it over multiple pages. This feature can insert row selector to every page.</li>
<li>Print preview feature</li>
<li>Portrait or landscape page orientation</li>
</ul>
<p><strong>The following bug has been fixed:</strong></p>
<ul>
<li>[BUG] .Net Grid wrongly filters the content if two filters (<strong>Grid.Filter</strong> and <strong>Column.Filter</strong>) are set simultaneously.</li>
</ul>
<p>Professionals working with complex systems will surely appreciate our efforts that make the code simpler and improve its reliability. Let&#8217;s create the best applications together!<br />
<br/></p>
]]></content:encoded>
			<wfw:commentRss>http://www.blog.dapfor.com/netgrid-2-7-0-released-reporting-features/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Realtime cell highlighting</title>
		<link>http://www.blog.dapfor.com/realtime-cell-highlighting</link>
		<comments>http://www.blog.dapfor.com/realtime-cell-highlighting#comments</comments>
		<pubDate>Wed, 15 Feb 2012 21:08:26 +0000</pubDate>
		<dc:creator>dapadm</dc:creator>
				<category><![CDATA[Performance]]></category>
		<category><![CDATA[trading]]></category>
		<category><![CDATA[cell highlighting]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[realtime]]></category>

		<guid isPermaLink="false">http://www.blog.dapfor.com/?p=82</guid>
		<description><![CDATA[Financial markets are lately becoming increasingly volatile and this generates a huge volume of information that has to be displayed in trading applications. Any changes of price or the number of sales/purchase offers for various financial instruments have to be displayed at trader’s screen. Visually it looks as highlighting relevant grid fields for specified time. [...]]]></description>
			<content:encoded><![CDATA[<p>Financial markets are lately becoming increasingly volatile and this generates a huge volume of information that has to be displayed in trading applications. Any changes of price or the number of sales/purchase offers for various financial instruments have to be displayed at trader’s screen. Visually it looks as highlighting relevant grid fields for specified time.</p>
<p>Practically any well-designed application should support highlighting of data that changes in real time. However, practical implementation of this feature may be complicated and may significantly impact application performance, thus limiting its usability at high market volatility environment.</p>
<p>In classic implementation of cell highlighting concept the programmer has to store last update time for each grid cell. When cell value changes, the cell should be redrawn with a new color (e.g. when price changes – with green or red background depending on change type). After a certain time interval cell background color should be restored. However, this seemingly simple task is usually hard to implement. Firstly, this depends on data storage method and data volume. If there are too many rows and columns, memory consumption can be fairly high. Secondly, it is necessary to track highlighting time for each cell to restore colors. Some cells may be outside visible area, and this should be considered to save CPU resources. Besides, it is not possible to create high-performance applications without knowing working principles of the painting system and its optimal usages.</p>
<pre>Grid grid = ...;
Cell cell = grid.Rows[10]["Bid"];
cell.Highlight(TimeSpan.FromSeconds(2), Color.Blue);</pre>
<p>&nbsp;</p>
<p>.Net Grid uses various optimizations that enable creation of efficient and high-performance applications. The programmer has only to use provided convenient interface and concentrate on application logic.</p>
<table>
<tbody>
<tr>
<td style="text-align: center;"><img class="size-full wp-image-84 aligncenter" title="Dapfor .Net Grid realtime updates" src="http://www.blog.dapfor.com/wp-content/uploads/2012/02/RealtimeUpdates.png" alt="Dapfor .Net Grid realtime updates" width="585" height="248" /></td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<p>The performance of the .Net Grid using various benchmarks demonstrates excellent results. It was really hard work to achieve such high values for various performance indicators. Here are some of them:</p>
<ul>
<li>High insertion rate: 100 000 rows/second.</li>
<li>High removal rate: 600 000 rows/second</li>
<li>High grouping rate: 60 000 rows/second</li>
<li>High real-time regrouping rate: 10 000 rows in a grid of 5 000 rows per second</li>
<li>High real-time filtering rate: 7 000 rows in a grid of 5 000 rows per second</li>
<li>Productive sort algorithms: 5 000 sorts in a grid of 5 000 rows per second</li>
<li>Low memory consumption: The grid of 100 000 rows will consume 16 MB</li>
</ul>
<p>Professionals working with complex systems will surely appreciate our efforts that make the code simpler and improve its reliability.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.blog.dapfor.com/realtime-cell-highlighting/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
