📄 renderers.cs
字号:
/*
* Renderers - A collection of useful renderers that are used to owner drawn a column in an ObjectListView
*
* Author: Phillip Piper
* Date: 27/09/2008 9:15 AM
*
* Change log:
* 2009-02-24 JPP - Work properly with ListViewPrinter again
* 2009-01-26 JPP - AUSTRALIA DAY (why aren't I on holidays!)
* - Major overhaul of renderers. Now uses IRenderer interface.
* - ImagesRenderer and FlagsRenderer<T> are now defunct.
* The names are retained for backward compatibility.
* 2009-01-23 JPP - Align bitmap AND text according to column alignment (previously
* only text was aligned and bitmap was always to the left).
* 2009-01-21 JPP - Changed to use TextRenderer rather than native GDI routines.
* 2009-01-20 JPP - Draw images directly from image list if possible. 30% faster!
* - Tweaked some spacings to look more like native ListView
* - Text highlight for non FullRowSelect is now the right color
* when the control doesn't have focus.
* - Commented out experimental animations. Still needs work.
* 2009-01-19 JPP - Changed to draw text using GDI routines. Looks more like
* native control this way. Set UseGdiTextRendering to false to
* revert to previous behavior.
* 2009-01-15 JPP - Draw background correctly when control is disabled
* - Render checkboxes using CheckBoxRenderer
* v2.0.1
* 2008-12-29 JPP - Render text correctly when HideSelection is true.
* 2008-12-26 JPP - BaseRenderer now works correctly in all Views
* 2008-12-23 JPP - Fixed two small bugs in BarRenderer
* v2.0
* 2008-10-26 JPP - Don't owner draw when in Design mode
* 2008-09-27 JPP - Separated from ObjectListView.cs
*
* Copyright (C) 2006-2008 Phillip Piper
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* If you wish to use this code in a closed source application, please contact phillip_piper@bigfoot.com.
*/
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Globalization;
using System.IO;
using System.Threading;
using System.Windows.Forms;
using System.Windows.Forms.VisualStyles;
namespace BrightIdeasSoftware
{
public interface IRenderer
{
/// <summary>
/// Render the whole item within an ObjectListView.
/// </summary>
/// <param name="e">The event</param>
/// <param name="g">A Graphics for rendering</param>
/// <param name="itemBounds">The bounds of the item</param>
/// <param name="rowObject">The model object to be drawn</param>
/// <returns>Return true to indicate that the event was handled and no further processing is needed.</returns>
bool RenderItem(DrawListViewItemEventArgs e, Graphics g, Rectangle itemBounds, Object rowObject);
/// <summary>
/// Render one cell within an ObjectListView when it is in Details mode.
/// </summary>
/// <param name="e">The event</param>
/// <param name="g">A Graphics for rendering</param>
/// <param name="cellBounds">The bounds of the cell</param>
/// <param name="rowObject">The model object to be drawn</param>
/// <returns>Return true to indicate that the event was handled and no further processing is needed.</returns>
bool RenderSubItem(DrawListViewSubItemEventArgs e, Graphics g, Rectangle cellBounds, Object rowObject);
/// <summary>
/// What is under the given point?
/// </summary>
/// <param name="hti"></param>
/// <param name="x">x co-ordinate</param>
/// <param name="y">y co-ordinate</param>
/// <remarks>This method should only alter HitTestLocation and/or UserData.</remarks>
void HitTest(OlvListViewHitTestInfo hti, int x, int y);
/// <summary>
/// When the value in the given cell is to be edited, where should the edit rectangle be placed?
/// </summary>
/// <param name="g"></param>
/// <param name="cellBounds"></param>
/// <param name="item"></param>
/// <param name="subItemIndex"></param>
/// <returns></returns>
Rectangle GetEditRectangle(Graphics g, Rectangle cellBounds, OLVListItem item, int subItemIndex);
}
/// <summary>
/// An AbstractRenderer is a do-nothing implementation of the IRenderer interface.
/// </summary>
[Browsable(true),
ToolboxItem(false)]
public class AbstractRenderer : Component, IRenderer
{
#region IRenderer Members
public virtual bool RenderItem(DrawListViewItemEventArgs e, Graphics g, Rectangle itemBounds, object rowObject)
{
return true;
}
public virtual bool RenderSubItem(DrawListViewSubItemEventArgs e, Graphics g, Rectangle cellBounds, object rowObject)
{
return false;
}
public virtual void HitTest(OlvListViewHitTestInfo hti, int x, int y)
{
}
public virtual Rectangle GetEditRectangle(Graphics g, Rectangle cellBounds, OLVListItem item, int subItemIndex)
{
return cellBounds;
}
#endregion
}
/// <summary>
/// This class provides compatibility for v1 RendererDelegates
/// </summary>
[ToolboxItem(false)]
internal class Version1Renderer : AbstractRenderer
{
public Version1Renderer(RenderDelegate renderDelegate)
{
this.RenderDelegate = renderDelegate;
}
/// <summary>
/// The renderer delegate that this renderer wraps
/// </summary>
public RenderDelegate RenderDelegate;
#region IRenderer Members
public override bool RenderSubItem(DrawListViewSubItemEventArgs e, Graphics g, Rectangle cellBounds, object rowObject)
{
if (this.RenderDelegate == null)
return base.RenderSubItem(e, g, cellBounds, rowObject);
else
return this.RenderDelegate(e, g, cellBounds, rowObject);
}
#endregion
}
/// <summary>
/// A BaseRenderer provides useful base level functionality for any custom renderer.
/// </summary>
/// <remarks>
/// <para>Subclasses will normally override the Render or OptionalRender method, and use the other
/// methods as helper functions.</para>
/// </remarks>
[Browsable(true),
ToolboxItem(true)]
public class BaseRenderer : AbstractRenderer
{
/// <summary>
/// Make a simple renderer
/// </summary>
public BaseRenderer()
{
}
#region Configuration Properties
/// <summary>
/// Can the renderer wrap lines that do not fit completely within the cell?
/// </summary>
[Category("Appearance"),
Description("Can the renderer wrap text that does not fit completely within the cell"),
DefaultValue(false)]
public bool CanWrap
{
get { return canWrap; }
set { canWrap = value; }
}
private bool canWrap = false;
/// <summary>
/// When rendering multiple images, how many pixels should be between each image?
/// </summary>
[Category("Appearance"),
Description("When rendering multiple images, how many pixels should be between each image?"),
DefaultValue(1)]
public int Spacing
{
get { return spacing; }
set { spacing = value; }
}
private int spacing = 1;
/// <summary>
/// Should text be rendered using GDI routines? This makes the text look more
/// like a native List view control.
/// </summary>
[Category("Appearance"),
Description("Should text be rendered using GDI routines?"),
DefaultValue(true)]
public bool UseGdiTextRendering
{
get {
if (this.IsPrinting)
return false; // Can't use GDI routines on a GDI+ printer context
else
return useGdiTextRendering;
}
set { useGdiTextRendering = value; }
}
private bool useGdiTextRendering = true;
#endregion
#region State Properties
/// <summary>
/// Get or set the aspect of the model object that this renderer should draw
/// </summary>
[Browsable(false),
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public Object Aspect
{
get
{
if (aspect == null)
aspect = column.GetValue(this.rowObject);
return aspect;
}
set { aspect = value; }
}
private Object aspect;
/// <summary>
/// What are the bounds of the cell that is being drawn?
/// </summary>
[Browsable(false),
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public Rectangle Bounds
{
get { return bounds; }
set { bounds = value; }
}
private Rectangle bounds;
/// <summary>
/// Get or set the OLVColumn that this renderer will draw
/// </summary>
[Browsable(false),
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public OLVColumn Column
{
get { return column; }
set { column = value; }
}
private OLVColumn column;
/// <summary>
/// Get/set the event that caused this renderer to be called
/// </summary>
[Browsable(false),
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public DrawListViewItemEventArgs DrawItemEvent
{
get { return drawItemEventArgs; }
set { drawItemEventArgs = value; }
}
private DrawListViewItemEventArgs drawItemEventArgs;
/// <summary>
/// Get/set the event that caused this renderer to be called
/// </summary>
[Browsable(false),
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public DrawListViewSubItemEventArgs Event
{
get { return eventArgs; }
set { eventArgs = value; }
}
private DrawListViewSubItemEventArgs eventArgs;
/// <summary>
/// Return the font to be used for text in this cell
/// </summary>
[Browsable(false),
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public Font Font
{
get
{
if (this.font != null || this.ListItem == null)
return this.font;
if (this.SubItem == null || this.ListItem.UseItemStyleForSubItems)
return this.ListItem.Font;
else
return this.SubItem.Font;
}
set
{
this.font = value;
}
}
private Font font;
/// <summary>
/// Should this renderer fill in the background before drawing?
/// </summary>
[Browsable(false),
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public bool IsDrawBackground
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -