Files
componentowl-astro/public/documentation/better-listview-express/data/chapter-data.html

438 lines
17 KiB
HTML
Raw Normal View History

<!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-listview-express/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="../../../blog/page/6/index.html"><img src="../resources/overview.gif" alt="Better ListView" class="ss"></a>
<div class="inside">
<div class="text">Better ListView: Ultimate .NET ListView replacement control for WinForms (C#, VB.NET)</div>
<span class="dbtn-c dbtn-hilight"><span class="dbtn-w"><a href="../../../betterlistview.exe" class="dbtn">Download</a></span></span>
<span class="dbtn-c"><span class="dbtn-w"><a href="../../../blog/page/6/index.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="../../../blog/page/6/index.html"><img src="../resources/overview.gif" alt="Better ListView" class="ss"></a>
<div class="inside">
<div class="text">Better ListView: Ultimate .NET ListView replacement control for WinForms (C#, VB.NET)</div>
<span class="dbtn-c dbtn-hilight"><span class="dbtn-w"><a href="../../../betterlistview.exe" class="dbtn">Download</a></span></span>
<span class="dbtn-c"><span class="dbtn-w"><a href="../../../blog/page/6/index.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-listview-express/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 ListView Express Documentation
</td>
<td class="footer-copyright">
Copyright © <a href="../../../index.html" target="_blank">ComponentOwl.com</a>
</td>
</tr></table>
</div></body>
</html>