438 lines
17 KiB
HTML
438 lines
17 KiB
HTML
|
|
<!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<Person></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<Person></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&lt;Person&gt; persons = new List&lt;Person&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">/// <summary>
|
||
|
|
/// Represents a simple data object (a person).
|
||
|
|
/// </summary>
|
||
|
|
internal sealed class Person
|
||
|
|
{
|
||
|
|
/// <summary>
|
||
|
|
/// Gets or sets the name of the person.
|
||
|
|
/// </summary>
|
||
|
|
/// <value>
|
||
|
|
/// The name of the person.
|
||
|
|
/// </value>
|
||
|
|
public string Name
|
||
|
|
{
|
||
|
|
get;
|
||
|
|
set;
|
||
|
|
}
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// Gets or sets the age of the person.
|
||
|
|
/// </summary>
|
||
|
|
/// <value>
|
||
|
|
/// The age of the person.
|
||
|
|
/// </value>
|
||
|
|
public int Age
|
||
|
|
{
|
||
|
|
get;
|
||
|
|
set;
|
||
|
|
}
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// Initializes a new instance of the <see cref = "Person" /> class.
|
||
|
|
/// </summary>
|
||
|
|
/// <param name = "name">The name of the person.</param>
|
||
|
|
/// <param name = "age">The age of the person.</param>
|
||
|
|
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">''' <summary>
|
||
|
|
''' Represents a simple data object (a person).
|
||
|
|
''' </summary>
|
||
|
|
Friend NotInheritable Class Person
|
||
|
|
|
||
|
|
''' <summary>
|
||
|
|
''' Gets or sets the name of the person.
|
||
|
|
''' </summary>
|
||
|
|
''' <value>
|
||
|
|
''' The name of the person.
|
||
|
|
''' </value>
|
||
|
|
Public Property Name() As String
|
||
|
|
Get
|
||
|
|
Return _mName
|
||
|
|
End Get
|
||
|
|
Set(ByVal value As String)
|
||
|
|
_mName = value
|
||
|
|
End Set
|
||
|
|
End Property
|
||
|
|
|
||
|
|
''' <summary>
|
||
|
|
''' Gets or sets the age of the person.
|
||
|
|
''' </summary>
|
||
|
|
''' <value>
|
||
|
|
''' The age of the person.
|
||
|
|
''' </value>
|
||
|
|
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
|
||
|
|
|
||
|
|
''' <summary>
|
||
|
|
''' Initializes a new instance of the <see cref = "Person" /> class.
|
||
|
|
''' </summary>
|
||
|
|
''' <param name = "Name">The name of the person.</param>
|
||
|
|
''' <param name = "Age">The age of the person.</param>
|
||
|
|
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>
|