335 lines
13 KiB
HTML
335 lines
13 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>Owner Drawing</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-multi-line.html"><strong>
|
||
« Multi-line Items</strong></a></td>
|
||
<td class="navigation-index"><a href="../../../quick-start-guide/better-listview/index.html"><strong>Index</strong></a></td>
|
||
<td class="navigation-next"><a href="chapter-performance.html"><strong>Performance »
|
||
</strong></a></td>
|
||
</tr></table>
|
||
<br><h1>Owner Drawing</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>Owner drawing allow to customize appearance of any element, element
|
||
part and the control itself:</p>
|
||
|
||
<p class="images"><img src="owner-draw.png"></p>
|
||
|
||
<h2>Drawing Over Control Parts</h2>
|
||
|
||
|
||
<p>The simple way to draw over control parts is by using drawing
|
||
events:</p>
|
||
|
||
<ul>
|
||
<li>
|
||
<p><span class="code">DrawBackground</span></p>
|
||
</li>
|
||
<li>
|
||
<p><span class="code">DrawColumnHeader</span></p>
|
||
</li>
|
||
<li>
|
||
<p><span class="code">DrawColumnHeaderBackground</span></p>
|
||
</li>
|
||
<li>
|
||
<p><span class="code">DrawGroup</span></p>
|
||
</li>
|
||
<li>
|
||
<p><span class="code">DrawGroupBackground</span></p>
|
||
</li>
|
||
<li>
|
||
<p><span class="code">DrawItem</span></p>
|
||
</li>
|
||
<li>
|
||
<p><span class="code">DrawItemBackground</span></p>
|
||
</li>
|
||
<li>
|
||
<p><span class="code">DrawInsertionMark</span></p>
|
||
</li>
|
||
</ul>
|
||
<p>Each of these events contains <span class="code">System.Drawing.Graphics</span>
|
||
object in event data with which custom drawing is possible. Areas of
|
||
drawing are also provided. For example, to draw inside item inner area,
|
||
there is a
|
||
<span class="code">BetterListViewDrawItemEventArgs.ItemBounds.BoundsInner</span>
|
||
property containing the rectangle.</p>
|
||
|
||
<br><hr>
|
||
<p class="note">If you want to paint outside element areas, set
|
||
<span class="code">OptimizedInvalidation</span> property to <span class="code">false</span>. This
|
||
will ensure your custom drawing code will be called in every redraw
|
||
cycle.</p>
|
||
<hr>
|
||
<br><h2>Replacing Default Drawing by Custom Drawing</h2>
|
||
|
||
|
||
<p>Owner drawing events are always called after the default drawing, so
|
||
it is possible only to draw over exisiting drawing. When you need turn off
|
||
some painting and do your own drawing instead of the default one (e.g.
|
||
draw rotated text instead the straight one), you have to create your
|
||
custom control inheriting from <span class="code">BetterListView</span>:</p>
|
||
|
||
<p><strong>C#</strong></p>
|
||
<pre class="prettyprint"><code class="lang-cs">class OwnerDrawBetterListView : BetterListView
|
||
{
|
||
// ...
|
||
}</code></pre>
|
||
|
||
<p><strong>Visual Basic</strong></p>
|
||
<pre class="prettyprint"><code class="lang-vb">Class OwnerDrawBetterListView Inherits BetterListView
|
||
' ...
|
||
End Class</code></pre>
|
||
|
||
<p>Then you can override one of the drawing methods:</p>
|
||
|
||
<ul>
|
||
<li>
|
||
<p><span class="code">OnDrawBackground</span></p>
|
||
</li>
|
||
<li>
|
||
<p><span class="code">OnDrawColumnHeader</span></p>
|
||
</li>
|
||
<li>
|
||
<p><span class="code">OnDrawGroup</span></p>
|
||
</li>
|
||
<li>
|
||
<p><span class="code">OnDrawGroupBackground</span></p>
|
||
</li>
|
||
<li>
|
||
<p><span class="code">OnDrawItem</span></p>
|
||
</li>
|
||
<li>
|
||
<p><span class="code">OnDrawItemBackground</span></p>
|
||
</li>
|
||
<li>
|
||
<p><span class="code">OnDrawInsertionMark</span></p>
|
||
</li>
|
||
</ul>
|
||
<p>This gives you more control over the painting, because your drawing
|
||
code can be called <strong><em>before</em></strong> or
|
||
<strong><em>after</em></strong> the default drawing, depending on where and if
|
||
you call base implementation.</p>
|
||
|
||
<p>Every part of the default drawing has a switch so you can turn the
|
||
default drawing off. For example, if you want not to draw default text on
|
||
some item, set <span class="code">BetterListViewDrawItemEventArgs.DrawText</span>
|
||
property to <span class="code">false</span>.</p>
|
||
|
||
<p>It is also possible to do custom drawing as the very last drawing of
|
||
the whole control. To do this, override <span class="code">DrawingRedrawCore</span>
|
||
method and do your drawing after calling the base implementation:</p>
|
||
|
||
<p><strong>C#</strong></p>
|
||
<pre class="prettyprint"><code class="lang-cs">protected override void DrawingRedrawCore(Graphics grfx)
|
||
{
|
||
base.DrawingRedrawCore(grfx);
|
||
|
||
// do your custom drawing
|
||
}</code></pre>
|
||
|
||
<p><strong>Visual Basic</strong></p>
|
||
<pre class="prettyprint"><code class="lang-vb">Protected Overrides Sub DrawingRedrawCore(grfx As Graphics)
|
||
|
||
MyBase.DrawingRedrawCore(grfx)
|
||
|
||
' do your custom drawing
|
||
|
||
End Sub</code></pre>
|
||
|
||
|
||
<h2>Overriding Item and Control States</h2>
|
||
|
||
|
||
<p>The appearance of element depends not only on its state, but also on
|
||
the control state.</p>
|
||
|
||
<p>If you override one of the drawing methods (e.g.
|
||
<span class="code">OnDrawItem</span>), you can modify event data before calling base
|
||
class implementation (e.g. <span class="code">base.OnDrawItem</span>).</p>
|
||
|
||
<p>For example, <span class="code">BetterListViewDrawItemEventArgs</span> contains
|
||
<span class="code">ItemStateInfo</span> property. By modifying this property, you can
|
||
force drawing item in any state you wish.</p>
|
||
|
||
<p><span class="code">BetterListViewDrawItemEventArgs</span> also contains two
|
||
properties regarding control state:</p>
|
||
|
||
<ul style="list-style:none">
|
||
<li>
|
||
<span class="code">DrawEnabled</span><ul style="list-style:none"><li>
|
||
<p>Draw item as if the control is in enabled state
|
||
(<span class="code">BetterListView.Enabled</span> is <span class="code">true</span>).</p>
|
||
</li></ul>
|
||
</li>
|
||
<li>
|
||
<span class="code">DrawFocused</span><ul style="list-style:none"><li>
|
||
<p>Draw item as if the control in in focused state
|
||
(<span class="code">BetterListView.Focused</span> is <span class="code">true</span>).</p>
|
||
</li></ul>
|
||
</li>
|
||
</ul>
|
||
<p>By default, these properties correspond to actual control's state,
|
||
but they can be modified. For example, one may want to set
|
||
<span class="code">DrawFocused</span> to true on every item that is selected, so the
|
||
item will be highlighted even if the control loses focus.</p>
|
||
|
||
<p>The control state properties are available only in the
|
||
<span class="code">BetterListViewItemEventArgs</span>, but element states can be
|
||
modified in all painting event handlers (also column headers and
|
||
groups).</p>
|
||
|
||
|
||
<h2>Sample Source Code</h2>
|
||
|
||
|
||
<p>The following sample shows owner drawing of item background:</p>
|
||
|
||
<p><strong>C#</strong></p>
|
||
<pre class="prettyprint"><code class="lang-cs">this.listView.BeginUpdate();
|
||
|
||
this.listView.Items.Add("Item with owner-drawn image and background.");
|
||
|
||
this.listView.View = BetterListViewView.Tile;
|
||
// turn off automatic image sizing to make space for image even when items do not have any images set
|
||
this.listView.LayoutOptions = (BetterListViewLayoutOptions.Auto & ~BetterListViewLayoutOptions.AutoSizeItemImage);
|
||
// set 4-pixel boundary around image
|
||
this.listView.LayoutItemsCurrent.ImagePadding = new Padding(4);
|
||
// set image size to be 50 by 50 pixels (it is possible to set image sizes for sub-items as well by adding more Size instances in the collection)
|
||
this.listView.LayoutItemsCurrent.ImageSizes = new ReadOnlyCollection<Size>(new[] { new Size(50, 50) });
|
||
|
||
this.listView.EndUpdate();
|
||
|
||
// we would like to draw over item's foreground (custom image)
|
||
this.listView.DrawItem += ListViewDrawItem;
|
||
// we would like to draw over item's background
|
||
this.listView.DrawItemBackground += ListViewDrawItemBackground;</code></pre>
|
||
|
||
<p><strong>Visual Basic</strong></p>
|
||
<pre class="prettyprint"><code class="lang-vb">ListView.BeginUpdate()
|
||
|
||
ListView.Items.Add("Item with owner-drawn image and background.")
|
||
|
||
ListView.View = BetterListViewView.Tile
|
||
' turn off automatic image sizing to make space for image even when items do not have any images set
|
||
ListView.LayoutOptions = (BetterListViewLayoutOptions.Auto And Not BetterListViewLayoutOptions.AutoSizeItemImage)
|
||
' set 4-pixel boundary around image
|
||
ListView.LayoutItemsCurrent.ImagePadding = New Padding(4)
|
||
' set image size to be 50 by 50 pixels (it is possible to set image sizes for sub-items as well by adding more Size instances in the collection)
|
||
ListView.LayoutItemsCurrent.ImageSizes = New ReadOnlyCollection(Of Size)(New Size() {New Size(50, 50)})
|
||
|
||
ListView.EndUpdate()
|
||
|
||
' we would like to draw over item's foreground (custom image)
|
||
AddHandler ListView.DrawItem, AddressOf ListViewDrawItem
|
||
' we would like to draw over item's background
|
||
AddHandler ListView.DrawItemBackground, AddressOf ListViewDrawItemBackground</code></pre>
|
||
|
||
<p><span class="code">DrawItem</span> event handler draws on the item image
|
||
area:</p>
|
||
|
||
<p><strong>C#</strong></p>
|
||
<pre class="prettyprint"><code class="lang-cs">void ListViewDrawItem(object sender, BetterListViewDrawItemEventArgs eventArgs)
|
||
{
|
||
eventArgs.Graphics.SmoothingMode = SmoothingMode.HighQuality;
|
||
|
||
Pen pen = new Pen(Color.BlueViolet, 2.5f);
|
||
|
||
// draw ellipse in the image area
|
||
eventArgs.Graphics.DrawEllipse(
|
||
pen,
|
||
eventArgs.ItemBounds.SubItemBounds[0].BoundsImage);
|
||
|
||
pen.Dispose();
|
||
}</code></pre>
|
||
|
||
<p><strong>Visual Basic</strong></p>
|
||
<pre class="prettyprint"><code class="lang-vb">Sub ListViewDrawItem(ByVal sender As Object, ByVal eventArgs As BetterListViewDrawItemEventArgs)
|
||
|
||
eventArgs.Graphics.SmoothingMode = SmoothingMode.HighQuality
|
||
|
||
Dim pen As New Pen(Color.BlueViolet, 2.5F)
|
||
|
||
' draw ellipse in the image area
|
||
eventArgs.Graphics.DrawEllipse(pen, eventArgs.ItemBounds.SubItemBounds(0).BoundsImage)
|
||
|
||
pen.Dispose()
|
||
|
||
End Sub</code></pre>
|
||
|
||
<p><span class="code">DrawItemBackground</span> event handler draws on the item
|
||
background area:</p>
|
||
|
||
<p><strong>C#</strong></p>
|
||
<pre class="prettyprint"><code class="lang-cs">void ListViewDrawItemBackground(object sender, BetterListViewDrawItemBackgroundEventArgs eventArgs)
|
||
{
|
||
Brush brush = new LinearGradientBrush(
|
||
eventArgs.ItemBounds.BoundsInner,
|
||
Color.FromArgb(64, Color.DarkSeaGreen),
|
||
Color.Transparent,
|
||
LinearGradientMode.ForwardDiagonal);
|
||
|
||
// draw over the item's background in the inner area
|
||
eventArgs.Graphics.FillRectangle(brush, eventArgs.ItemBounds.BoundsInner);
|
||
|
||
brush.Dispose();
|
||
}</code></pre>
|
||
|
||
<p><strong>Visual Basic</strong></p>
|
||
<pre class="prettyprint"><code class="lang-vb">Sub ListViewDrawItemBackground(ByVal sender As Object, ByVal eventArgs As BetterListViewDrawItemBackgroundEventArgs)
|
||
|
||
Dim brush As Brush = New LinearGradientBrush(
|
||
eventArgs.ItemBounds.BoundsInner,
|
||
Color.FromArgb(64, Color.DarkSeaGreen),
|
||
Color.Transparent,
|
||
LinearGradientMode.ForwardDiagonal)
|
||
|
||
' draw over the item's background in the inner area
|
||
eventArgs.Graphics.FillRectangle(brush, eventArgs.ItemBounds.BoundsInner)
|
||
|
||
brush.Dispose()
|
||
|
||
End Sub</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-multi-line.html"><strong>
|
||
« Multi-line Items</strong></a></td>
|
||
<td class="navigation-index"><a href="../../../quick-start-guide/better-listview/index.html"><strong>Index</strong></a></td>
|
||
<td class="navigation-next"><a href="chapter-performance.html"><strong>Performance »
|
||
</strong></a></td>
|
||
</tr></table>
|
||
<br><table class="footer"><tr>
|
||
<td class="footer-title">Better ListView Documentation
|
||
</td>
|
||
<td class="footer-copyright">
|
||
Copyright © 2010-2012 <a href="../../../index.html" target="_blank">ComponentOwl.com</a>
|
||
</td>
|
||
</tr></table>
|
||
</div></body>
|
||
</html>
|