Files

437 lines
17 KiB
HTML
Raw Permalink 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>Data Binding</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-context-menus.html"><strong>
« Context Menus</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-drag-drop.html"><strong>Drag and Drop »
</strong></a></td>
</tr></table>
<br><h1>Data Binding</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 supports both <strong><em>lookup</em></strong> binding and
<strong><em>complex</em></strong> binding of user-provided data.</p>
<p>Complex binding allows you use any list-type collection (implementing
<span class="code">IList</span> or <span class="code">IListSource</span>) to the control. Complex
binding is not a feature of all WinForms controls.</p>
<p>Regular .NET ListView does not support binding of lists.</p>
<p>Lookup binding is supported on any WinForms control automatically, so
we won't cover the topic here.</p>
<h2>Basic Data Binding</h2>
<p>To bind a custom <span class="code">IList</span> instance, set the
<span class="code">DataSource</span> property:</p>
<p><strong>C#</strong></p>
<pre class="prettyprint"><code class="lang-cs">listView.DataSource = myList; // myList is of type List&lt;Person&gt;</code></pre>
<p><strong>Visual Basic</strong></p>
<pre class="prettyprint"><code class="lang-vb">ListView.DataSource = myList ' myList is of type List(Of Person)()</code></pre>
<p>This fills Better ListView with objects in
<span class="code">myList</span>:</p>
<p class="images"><img src="data-simple.png"></p>
<p>When converting <span class="code">Person</span> objects to items, Better
ListView first looks if there is a <span class="code">TypeConverter</span> defined to
use <span class="code">ConvertToString</span> method. If not, standard
<span class="code">ToString</span> method is called to obtain item text.</p>
<h2>Displaying Custom Properties</h2>
<p>To display value of some specific property of the bound object, use
the <span class="code">DisplayMember</span> property. For example, if we set the
<span class="code">DisplayMember</span> to "Age", Better ListView will represent each
<span class="code">Person</span> object by its <span class="code">Age</span> property:</p>
<p class="images"><img src="data-displaymember.png"></p>
<p>The <span class="code">DisplayMember</span> property can be set on columns as
well, so that each column can display another property of the bound
object.</p>
<h2>Working with Values instead of Items</h2>
<p>Each column in Better ListView can represent different property of
the bound object. The property can be specified using
<span class="code">ValueMember</span> property (also on each column using
<span class="code">BetterListViewColumnHeader.ValueMember</span>). When specified, the
property value can be accessed using the
<span class="code">BetterListViewItem.Value</span>
(<span class="code">BetterListViewSubItem.Value</span>).</p>
<p>For example, if we set <span class="code">ValueMember</span> to "Age", each item
will have the <span class="code">Value</span> property set to corresponding short with
the person's age.</p>
<p>You can also use following properties to work with selection in
terms of the bound objects (values):</p>
<ul>
<li>
<p><span class="code">SelectedValue</span></p>
</li>
<li>
<p><span class="code">SelectedValues</span></p>
</li>
</ul>
<h2>Binding Columns</h2>
<p>It is possible to display object properties in columns simply by
setting <span class="code">DataBindColumns</span> to <span class="code">true</span>. This will cause
Better ListView to generate column for each public property of provided
list item type automatically:</p>
<p class="images"><img src="data-bindcolumns.png"></p>
<p>Here the <span class="code">List&lt;Person&gt;</span> object is bound. The
<span class="code">Person</span> type contains three public properties:</p>
<ul>
<li>
<p><span class="code">Name</span> (<span class="code">String</span>)</p>
</li>
<li>
<p>Age (<span class="code">short</span>)</p>
</li>
<li>
<p><span class="code">Gender</span> (enum of type
<span class="code">PersonGender</span>)</p>
</li>
</ul>
<p>Column header texts are generated from property names.
<span class="code">DisplayNameAttribute</span> can be used on the property to specify
custom name (as used in the <strong><em>Age</em></strong> column).</p>
<h2>Binding Position</h2>
<p>Data binding mechanism in WinForms keeps information about current
position in the bound list. Better ListView synchronizes current position
with its selection.</p>
<p>To turn off this behvior, set <span class="code">DataBindPosition</span> property
to <span class="code">false</span>. In this case, Better ListView selection will be
independent on current position in the bound list.</p>
<h2>Sorting Items</h2>
<p>Item sorting can be a nontrivial update of the bound list (which is
unsupported by the standard data binding mechanism).</p>
<p><span class="code">SortVirtual</span> property should be set to <span class="code">true</span>
to turn off physical update of the <span class="code">Items</span> collection. The
columns will still display sort glyphs and the <span class="code">SortList</span> will
contain new sort state information, so the manual sorting is
possible.</p>
<p>For example, if we have <span class="code">Person[]</span> array bound, we can
sort it manually in the <span class="code">AfterItemSort</span> event handler this
way:</p>
<p><strong>C#</strong></p>
<pre class="prettyprint"><code class="lang-cs">// get values from the data source
Person[] values = (Person[])this.listView.DataSource;
// get listview items as keys
BetterListViewItem[] keys = new BetterListViewItem[values.Length];
this.listView.Items.CopyTo(keys, 0);
// create custom comparer
BetterListViewItemComparer comparer = this.listView.ItemComparer;
comparer.SetSortList(this.listView.SortList, this.listView.Columns, true);
// sort the data
Array.Sort(keys, values, comparer);
// refresh view
((CurrencyManager)this.listView.BindingContext[this.listView.DataSource]).Refresh();</code></pre>
<p><strong>Visual Basic</strong></p>
<pre class="prettyprint"><code class="lang-vb">' get values from the data source
Dim values As Person() = DirectCast(Me.ListView.DataSource, Person())
' get listview items as keys
Dim keys As BetterListViewItem() = New BetterListViewItem(values.Length - 1) {}
Me.ListView.Items.CopyTo(keys, 0)
' create custom comparer
Dim comparer As BetterListViewItemComparer = Me.ListView.ItemComparer
comparer.SetSortList(Me.ListView.SortList, Me.ListView.Columns, True)
' sort the data
Array.Sort(keys, values, comparer)
' refresh view
DirectCast(Me.ListView.BindingContext(Me.ListView.DataSource), CurrencyManager).Refresh()</code></pre>
<p>Sorting can also be achieved by using <span class="code">DataTable</span>,
<span class="code">DataView</span> or other type that supports sorting while bound to a
control (such types implement <span class="code">IBindingList</span>) as a data
source:</p>
<p><strong>C#</strong></p>
<pre class="prettyprint"><code class="lang-cs">// get data source
DataTable dataTable = (DataTable)this.listView.DataSource;
// set sort
dataTable.DefaultView.Sort = "Name ASC, Age DESC";
// refresh view
(((CurrencyManager)this.listView.BindingContext[this.listView.DataSource]).Refresh();</code></pre>
<p><strong>Visual Basic</strong></p>
<pre class="prettyprint"><code class="lang-vb">' get data source
Dim dataTable As DataTable = DirectCast(Me.ListView.DataSource, DataTable)
' set sort
dataTable.DefaultView.Sort = "Name ASC, Age DESC"
' refresh view
DirectCast(Me.ListView.BindingContext(Me.ListView.DataSource), CurrencyManager).Refresh()</code></pre>
<h2>Sorting by Value</h2>
<p>Items can be sorted by other than displayed value when
<span class="code">ValueMember</span> property is set.</p>
<p>For example, we have a <span class="code">DataTable</span> with columns
"<strong><em>PercentDone</em></strong>" - which contains numeric values - and
"<strong><em>PercentDoneDisplay</em></strong>" which contains corresponding
values for display (e.g. rounded, with percent sign). Setting
<span class="code">DisplayMember</span> property on the column for percentage to
"<strong><em>PercentDoneDisplay</em></strong>" and <span class="code">ValueMember</span>
property to "<strong><em>PercentDone</em></strong>" causes sorting according to
value in numeric column.</p>
<p>Values are used for sorting only when the <span class="code">Key</span> property
of a sub-item is not available. The <span class="code">Key</span> property has the
highest priority when sorting, then the <span class="code">Value</span> property, and
then the <span class="code">Text</span> property.</p>
<p>Following image shows multi-column sorting of a bound
<span class="code">DataTable</span> - the table is sorted according to column with
aspect ratio enumeration (invisible, showing another column with display
values) and a numeric column (percentage):</p>
<p class="images"><img src="data-sort.png"></p>
<h2>Reordering Items and Columns</h2>
<p>When some data is bound to Better ListView and columns are
reordered, the control automatically performs refresh of the data (this is
the case of <span class="code">ColumnReorderMode</span> set to
<span class="code">Enabled</span>).</p>
<p>Automatic item reordering is restricted to happen on the same item
level or between different levels, but only when none of the levels are
the top level.</p>
<p>Item reordering with data binding should be implemented in the
similar manner as item sorting. First, set the
<span class="code">ItemReorderMode</span> property to <span class="code">Custom</span>. Then
implement the custom reordering logic on data source in the
<span class="code">AfterItemReorder</span> event handler.</p>
<h2>Sample Source Code</h2>
<p>The following sample will binds a list of <span class="code">Person</span>
objects to Better ListView:</p>
<p><strong>C#</strong></p>
<pre class="prettyprint"><code class="lang-cs">// create a list of Person objects
List&amp;lt;Person&amp;gt; persons = new List&amp;lt;Person&amp;gt;(new[]
{
new Person("Lee Adama", 45),
new Person("Sally Gordon", 26),
new Person("John Grant", 18),
new Person("Susan Hutchinson", 37)
});
// create columns automatically
this.listView.DataBindColumns = true;
// populate ListView with our data
this.listView.DataSource = persons;</code></pre>
<p><strong>Visual Basic</strong></p>
<pre class="prettyprint"><code class="lang-vb">' create a list of Person objects
Dim persons As New List(Of Person)(
New Person() { _
New Person("Lee Adama", 45),
New Person("Sally Gordon", 26),
New Person("John Grant", 18),
New Person("Susan Hutchinson", 37)
})
' create columns automatically
ListView.DataBindColumns = True
' populate ListView with our data
ListView.DataSource = persons</code></pre>
<p>The <span class="code">Person</span> class itself is particularly simple - it
does not need to provide anything else than public properties which are
bound:</p>
<p><strong>C#</strong></p>
<pre class="prettyprint"><code class="lang-cs">/// &lt;summary&gt;
/// Represents a simple data object (a person).
/// &lt;/summary&gt;
internal sealed class Person
{
/// &lt;summary&gt;
/// Gets or sets the name of the person.
/// &lt;/summary&gt;
/// &lt;value&gt;
/// The name of the person.
/// &lt;/value&gt;
public string Name
{
get;
set;
}
/// &lt;summary&gt;
/// Gets or sets the age of the person.
/// &lt;/summary&gt;
/// &lt;value&gt;
/// The age of the person.
/// &lt;/value&gt;
public int Age
{
get;
set;
}
/// &lt;summary&gt;
/// Initializes a new instance of the &lt;see cref = "Person" /&gt; class.
/// &lt;/summary&gt;
/// &lt;param name = "name"&gt;The name of the person.&lt;/param&gt;
/// &lt;param name = "age"&gt;The age of the person.&lt;/param&gt;
public Person(string name, int age)
{
Name = name;
Age = age;
}
}</code></pre>
<p><strong>Visual Basic</strong></p>
<pre class="prettyprint"><code class="lang-vb">''' &lt;summary&gt;
''' Represents a simple data object (a person).
''' &lt;/summary&gt;
Friend NotInheritable Class Person
''' &lt;summary&gt;
''' Gets or sets the name of the person.
''' &lt;/summary&gt;
''' &lt;value&gt;
''' The name of the person.
''' &lt;/value&gt;
Public Property Name() As String
Get
Return _mName
End Get
Set(ByVal value As String)
_mName = value
End Set
End Property
''' &lt;summary&gt;
''' Gets or sets the age of the person.
''' &lt;/summary&gt;
''' &lt;value&gt;
''' The age of the person.
''' &lt;/value&gt;
Public Property Age() As Integer
Get
Return _mAge
End Get
Set(ByVal value As Integer)
_mAge = value
End Set
End Property
Private _mName As String
Private _mAge As Integer
''' &lt;summary&gt;
''' Initializes a new instance of the &lt;see cref = "Person" /&gt; class.
''' &lt;/summary&gt;
''' &lt;param name = "Name"&gt;The name of the person.&lt;/param&gt;
''' &lt;param name = "Age"&gt;The age of the person.&lt;/param&gt;
Public Sub New(ByVal Name As String, ByVal Age As Integer)
Me.Name = Name
Me.Age = Age
End Sub
End Class</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-context-menus.html"><strong>
« Context Menus</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-drag-drop.html"><strong>Drag and Drop »
</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>