Files
componentowl-astro/public/documentation/better-thumbnail-browser/data/chapter-sort.html

464 lines
19 KiB
HTML
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:xlink="http://www.w3.org/1999/xlink">
<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
<title>Sorting Items</title>
<link href="style.css" rel="stylesheet" type="text/css">
<link href="prettify.css" type="text/css" rel="stylesheet">
<script type="text/javascript" src="prettify.js"></script><script type="text/javascript" src="lang-vb.js"></script><link href="../resources/main.css" media="screen" rel="stylesheet" type="text/css">
</head>
<body onload="prettyPrint()"><div class="placing">
<br><table class="navigation"><tr>
<td class="navigation-previous"><a href="chapter-serialization.html"><strong>
« Serialization</strong></a></td>
<td class="navigation-index"><a href="../../../better-thumbnail-browser/documentation.html"><strong>Index</strong></a></td>
<td class="navigation-next"><a href="chapter-sub-items.html"><strong>Sub-items »
</strong></a></td>
</tr></table>
<br><h1>Sorting Items</h1>
<div class="banner">
<a href="../../../better-thumbnail-browser.html"><img src="../resources/better-thumbnail-browser-overview.gif" alt="Better Thumbnail Browser" class="ss"></a>
<div class="inside">
<div class="text">Better Thumbnail Browser for .NET (C#, VB) - Image thumbnail viewing and loading control</div>
<span class="dbtn-c dbtn-hilight"><span class="dbtn-w"><a href="../../../betterthumbnailbrowser.exe" class="dbtn">Download</a></span></span>
<span class="dbtn-c"><span class="dbtn-w"><a href="../../../better-thumbnail-browser.html" class="dbtn">More Info</a></span></span>
</div>
</div>
<p>Better ListView has extensive support for sorting, while it is usually
very easy (few lines of code) to customize sorting by one's needs.</p>
<p>The only action needed to enable sorting is to set
<span class="code">BetterListViewColumnHeader.Style</span> to <span class="code">Sortable</span> on
every column you wish to enable user sorting.</p>
<h2>Multi-Column Sorting</h2>
<p>When the <span class="code">AllowMultiColumnSorting</span> property is set to
<span class="code">true</span> and there are multiple columns with <span class="code">Style</span>
property set to <span class="code">Sortable</span>, user can sort items by multiple
columns by holding <strong><em>Shift</em></strong> key while clicking on the
sortable columns.</p>
<p>Here is a list of movies sorted by two columns:</p>
<p class="images"><img src="sorting-multi-column.png"></p>
<p>In this case, user first clicked on the
<strong><em>Director</em></strong> column, and then twice on the
<strong><em>Title</em></strong> column while holding <strong><em>Shift</em></strong>
key. Now the list is sorted by the director's name in ascending order, but
when director names are the same, their movie titles are sorted in
descending order.</p>
<p>Sorted columns can also be un-sorted by clicking on them while
holding a <strong><em>Control</em></strong> key.</p>
<h2>Multi-Column Sorting from User Code</h2>
<p>Better ListView uses list-based data structure called
<span class="code">SortList</span> (accessible with the property of the same name) to
store current sort state. <span class="code">SortList</span> contains indices and sort
orders of the respective columns.</p>
<p>When a single solumn is sorted, <span class="code">SortList</span> contains one
<span class="code">BetterListViewSortInfo</span> instance with index and sort order of
that column.</p>
<p><span class="code">SortList</span> can be cloned (it is actually cloned every
time you get a <span class="code">SortList</span> instance through the
<span class="code">SortList</span> property getter). It is possible to copy sort state
of one ListView to another:</p>
<p><strong>C#</strong></p>
<pre class="prettyprint"><code class="lang-cs">listView2.SortList = listView1.SortList;</code></pre>
<p><strong>Visual Basic</strong></p>
<pre class="prettyprint"><code class="lang-vb">listView2.SortList = listView1.SortList</code></pre>
<p>The list gets sorted when <span class="code">SortList</span> property is
set.</p>
<h2>Sorting Item Hierarchy</h2>
<p><strong><em><a href="chapter-item-hierarchy.html">Child items</a></em></strong>
are sorted by default. If you want to disable hierarchical sorting, simply
set <span class="code">BetterListViewItem.AllowSortChildItems</span> property to
<span class="code">false</span>.</p>
<p>Another approach to more customized hierarchical sorting (e.g. when
you want to sort child items with different comparer than parent items) is
to use <span class="code">Sort</span> method of the item collection itself (be it
<span class="code">BetterListView.Items</span> or
<span class="code">BetterListViewItem.ChildItems</span>).</p>
<h2>Sorting by Key or Value</h2>
<p>Sometimes, there are items with non-textual data that cannot be
sorted simply by string comparison. For example, there can be progress
bars or other graphic gauges on items. To sort such items (sub-items),
Better ListView can gather data from two other properties:</p>
<ul style="list-style:none">
<li>
<span class="code">BetterListViewItem.Key</span>
(<span class="code">BetterListViewSubItem.Key</span>)<ul style="list-style:none"><li>
<p>.<span class="code">IComparable</span> object explicitly specified by the
user for item comparison purposes.</p>
</li></ul>
</li>
<li>
<span class="code">BetterListViewItem.Value</span>
(<span class="code">BetterListViewSubItem.Value</span>)<ul style="list-style:none"><li>
<p>Value of a property from bound data source specified by the
ValueMember property of the corresponding column (see <strong><em><a href="chapter-data.html">Data Binding</a></em></strong> for more
information).</p>
</li></ul>
</li>
</ul>
<p>There are three sorting methods that are possible on each column
separately (see
<span class="code">BetterListViewColumnHeader.SortMethod</span>):</p>
<ul style="list-style:none">
<li>
<span class="code">Auto</span><ul style="list-style:none"><li>
<p><span class="code">Key</span> is used primarily for comparison; if not
available the comparer falls back to <span class="code">Value</span>, and if even
this is not available, <span class="code">Text</span> is used.</p>
</li></ul>
</li>
<li>
<span class="code">Text</span><ul style="list-style:none"><li>
<p><span class="code">Text</span> is always used for comparison.</p>
</li></ul>
</li>
<li>
<span class="code">Key</span><ul style="list-style:none"><li>
<p><span class="code">Key</span> is used always for comparison.</p>
</li></ul>
</li>
</ul>
<h2>Custom and Natural (Alphanumeric) Item Comparers</h2>
<p>Better ListView uses <span class="code">BetterListView.ItemComparer</span> for
item comparison. You can set this property using custom comparer of type
<span class="code">BetterListViewItemComparer</span>.</p>
<p>There are two comparers already implemented in Better ListView.
These can be used publicly and extended:</p>
<ul>
<li>
<p><span class="code">BetterListViewDefaultItemComparer</span></p>
</li>
<li>
<p><span class="code">BetterListViewNaturalItemComparer</span></p>
</li>
</ul>
<p>The difference between the two is explained in <strong><em><a href="chapter-sort.html#alphanumeric-sorting">Alphanumeric Sorting</a></em></strong> section
below.</p>
<h2>Making a Custom Item Comparer</h2>
<p>To make a new item comparer with custom comparison rules, create a
new class inheriting from <span class="code">BetterListViewItemComparer</span>.</p>
<p><span class="code">BetterListViewItemComparer</span> implements several methods
doing item comparison on various levels. These methods can be overriden to
customize sorting behavior:</p>
<ul style="list-style:none">
<li>
<span class="code">Compare</span><ul style="list-style:none"><li>
<p>Compares two items. This is the core method for item
comparison. <span class="code">BetterListViewItemComparer</span> implements
multi-column sorting here and calls <span class="code">CompareSubItems</span> and
<span class="code">CompareEqualItems</span> from here.</p>
</li></ul>
</li>
<li>
<span class="code">CompareSubItems</span><ul style="list-style:none"><li>
<p>Compares two sub-items in the same column. Here the
<span class="code">BetterListViewItemComparer</span> implements sorting methods
(specified by <span class="code">BetterListViewColumnHeader.SortMethod</span>
property) and calls <span class="code">CompareValues</span> from here. The
sub-items are compared here either by value, key or by text.</p>
</li></ul>
</li>
<li>
<span class="code">CompareValues</span><ul style="list-style:none"><li>
<p>Compares two arbitrary <span class="code">IComparable</span> values in the
specified order. <span class="code">BetterListViewItemComparer</span> implements
comparison with possible <span class="code">null</span> values and regarding the
sort order.</p>
</li></ul>
</li>
<li>
<span class="code">CompareEqualItems</span><ul style="list-style:none"><li>
<p>When two items are considered equal in the
<span class="code">Compare</span> method, <span class="code">BetterListViewItemComparer</span>
calls this method, which compares the items by their index.</p>
</li></ul>
</li>
</ul>
<p>It is not necessary to override all the above methods, since they
are already implemented in the <span class="code">BetterListViewItemComparer</span>
base class.</p>
<p>For example, if we want to create a custom comparer that compares
items accroding to their check box state:</p>
<p class="images"><img src="sorting-custom.png"></p>
<p>we only have to override the <span class="code">Compare</span> method. If the
check box state is the leading criterion for sorting, we implement the
comparison and then call <span class="code">Compare</span> method of the base class (to
allow for multi-column sorting, further sorting according to item text
etc.). Our custom "checkbox" comparer would look like this:</p>
<p><strong>C#</strong></p>
<pre class="prettyprint"><code class="lang-cs">class CheckBoxItemComparer : BetterListViewItemComparer
{
public override int Compare(BetterListViewItem itemA, BetterListViewItem itemB)
{
if (itemA != null &amp;&amp;
itemB != null)
{
int valueA = (itemA.Checked
? 1
: 0);
int valueB = (itemB.Checked
? 1
: 0);
int result = valueA.CompareTo(valueB);
if (result != 0)
{
return result;
}
}
return base.Compare(itemA, itemB);
}
}</code></pre>
<p><strong>Visual Basic</strong></p>
<pre class="prettyprint"><code class="lang-vb">Class CheckBoxItemComparer Inherits BetterListViewItemComparer
Public Overrides Function Compare(itemA As BetterListViewItem, itemB As BetterListViewItem) As Integer
If itemA IsNot Nothing AndAlso itemB IsNot Nothing Then
Dim valueA As Integer = (If(itemA.Checked, 1, 0))
Dim valueB As Integer = (If(itemB.Checked, 1, 0))
Dim result As Integer = valueA.CompareTo(valueB)
If result &lt;&gt; 0 Then
Return result
End If
End If
Return MyBase.Compare(itemA, itemB)
End Function
End Class</code></pre>
<p>On the contrary, if you want to make check box the least important
criteria in the sorting, put the comparison in the
<span class="code">CompareEqualItems</span> method.</p>
<p>Finally, if the comparison result of the custom comparer depends on
other sub-items, consider implementing the <span class="code">CompareSubItems</span>
method.</p>
<h2>Highlighting the Sorted Column</h2>
<p class="images"><img src="sorting-highlight.png"></p>
<p>There are two properties influencing column highlighting:</p>
<ul style="list-style:none">
<li>
<span class="code">SortedColumnsRowsHighlight</span><ul style="list-style:none"><li>
<p>Affects sorted column highlighting.</p>
</li></ul>
</li>
<li>
<span class="code">ColorSortedColumn</span><ul style="list-style:none"><li>
<p>Affects color of the highlighted column.</p>
</li></ul>
</li>
</ul>
<p>The column highlighting is practical in multi-column sorting,
because it shows which column is the major one (the first sorted). By
default, the first sorted column is highlighted in multi-column
sorting.</p>
<h2>
<a name="alphanumeric-sorting" id="alphanumeric-sorting"></a>Alphanumeric Sorting</h2>
<p class="images"><img src="sorting-alphanum1.png"><img src="sorting-alphanum2.png"></p>
<p>The most popular way of sorting (left image) is comparing text
values of items by their ordinal value because such comparison is
straightforward to implement.</p>
<p>Better ListView supports also alphanumeric (or natural) ordering of
items, where numbers and words are compared separately. This gives us more
convenient results (right image - see how numbers are ordered by their
true value).</p>
<p>To use alphanumeric sorting, simply write:</p>
<p><strong>C#</strong></p>
<pre class="prettyprint"><code class="lang-cs">listView.ItemComparer = new BetterListViewNaturalItemComparer();</code></pre>
<p><strong>Visual Basic</strong></p>
<pre class="prettyprint"><code class="lang-vb">ListView.ItemComparer = New BetterListViewNaturalItemComparer()</code></pre>
<h2>Suspending the Automatic Sorting</h2>
<p>When items are sorted, any change in items (e.g. item added, label
edited...) causes updating the items to keep them sorted. It is convenient
in some situations to suspend this mechanism. For example, when one does
several changes in items and want to re-sort them in the end.</p>
<p>Better ListView provides <span class="code">SuspendSort</span> and
<span class="code">ResumeSort</span> to achieve just this. These methods work in the
same fashion as <span class="code">BeginUpdate</span> / <span class="code">EndUpdate</span>. It is
possible to nest these methods using multiple calls, so
<span class="code">ResumeSort</span> have to be called same number of times as
<span class="code">SuspendSort</span> to actually resume the automatic sorting.</p>
<p>The <span class="code">ResumeSort</span> have a boolean parameter specifying
whether this call should also update item order (perform re-sorting). If
you pass <span class="code">true</span> to this method, item update (re-sorting) will
not be executed and is done after some change is made to items.</p>
<h2>Unsorting</h2>
<p>Sorting affects the order of items in the list and also introduces
visual cues of the sort state. These can be removed by simply calling
<span class="code">Unsort</span> method.</p>
<p>Alternatively, setting <span class="code">BetterListView.SortList</span> to
either empty <span class="code">SortList</span> or null does the same job.</p>
<h2>Sample Source Code</h2>
<p><strong>C#</strong></p>
<pre class="prettyprint"><code class="lang-cs">this.listView.BeginUpdate();
this.listView.Columns.Add("Text");
this.listView.Columns[0].Style = BetterListViewColumnHeaderStyle.Sortable;
this.listView.Items.AddRange(
new[]
{
"Beta 009",
"Alpha 113",
"Charlie2",
"Alpha 96",
"Beta 030",
"Charlie1"
});
// suspend sorting so that items will not be sorted by setting ItemComparer (we let user to sort them by himself by clicking the column)
this.listView.SuspendSort();
// set natural item comparer provided by Better ListView
// to reset comparer, simply set it to 'null' or new instance of 'BetterListViewItemComparer'
this.listView.ItemComparer = new BetterListViewNaturalItemComparer();
// resume sorting so that user will be able to sort items by himself
this.listView.ResumeSort(true);
this.listView.EndUpdate();</code></pre>
<p><strong>Visual Basic</strong></p>
<pre class="prettyprint"><code class="lang-vb">ListView.BeginUpdate()
ListView.Columns.Add ("Text")
ListView.Columns (0).Style = BetterListViewColumnHeaderStyle.Sortable
ListView.Items.AddRange(
New String() {
"Beta 009",
"Alpha 113",
"Charlie2",
"Alpha 96",
"Beta 030",
"Charlie1"
})
' suspend sorting so that items will not be sorted by setting ItemComparer (we let user to sort them by himself by clicking the column)
ListView.SuspendSort()
' set natural item comparer provided by Better ListView
' to reset comparer, simply set it to 'null' or new instance of 'BetterListViewItemComparer'
ListView.ItemComparer = New BetterListViewNaturalItemComparer()
' resume sorting so that user will be able to sort items by himself
ListView.ResumeSort (True)
ListView.EndUpdate()</code></pre>
<br><div class="banner">
<a href="../../../better-thumbnail-browser.html"><img src="../resources/better-thumbnail-browser-overview.gif" alt="Better Thumbnail Browser" class="ss"></a>
<div class="inside">
<div class="text">Better Thumbnail Browser for .NET (C#, VB) - Image thumbnail viewing and loading control</div>
<span class="dbtn-c dbtn-hilight"><span class="dbtn-w"><a href="../../../betterthumbnailbrowser.exe" class="dbtn">Download</a></span></span>
<span class="dbtn-c"><span class="dbtn-w"><a href="../../../better-thumbnail-browser.html" class="dbtn">More Info</a></span></span>
</div>
</div>
<table class="navigation"><tr>
<td class="navigation-previous"><a href="chapter-serialization.html"><strong>
« Serialization</strong></a></td>
<td class="navigation-index"><a href="../../../better-thumbnail-browser/documentation.html"><strong>Index</strong></a></td>
<td class="navigation-next"><a href="chapter-sub-items.html"><strong>Sub-items »
</strong></a></td>
</tr></table>
<br><table class="footer"><tr>
<td class="footer-title">Better Thumbnail Browser Documentation
</td>
<td class="footer-copyright">
Copyright © 2010-2012  <a href="../../../index.html" target="_blank">ComponentOwl.com</a>
</td>
</tr></table>
</div></body>
</html>