|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System.Drawing;
namespace System.Windows.Forms;
/// <summary>
/// This class contains the information a user needs to paint ListView items.
/// </summary>
public class DrawListViewItemEventArgs : EventArgs
{
/// <summary>
/// Creates a new DrawListViewItemEventArgs with the given parameters.
/// </summary>
public DrawListViewItemEventArgs(
Graphics graphics,
ListViewItem item,
Rectangle bounds,
int itemIndex,
ListViewItemStates state)
{
Graphics = graphics.OrThrowIfNull();
Item = item.OrThrowIfNull();
Bounds = bounds;
ItemIndex = itemIndex;
State = state;
}
/// <summary>
/// Graphics object with which painting should be done.
/// </summary>
public Graphics Graphics { get; }
/// <summary>
/// The item to be painted.
/// </summary>
public ListViewItem Item { get; }
/// <summary>
/// The rectangle outlining the area in which the painting should be done.
/// </summary>
public Rectangle Bounds { get; }
/// <summary>
/// The index of the item that should be painted.
/// </summary>
public int ItemIndex { get; }
/// <summary>
/// Miscellaneous state information.
/// </summary>
public ListViewItemStates State { get; }
/// <summary>
/// Causes the item do be drawn by the system instead of owner drawn.
/// </summary>
public bool DrawDefault { get; set; }
/// <summary>
/// Draws the item's background.
/// </summary>
public void DrawBackground()
{
using var backBrush = Item.BackColor.GetCachedSolidBrushScope();
Graphics.FillRectangle(backBrush, Bounds);
}
/// <summary>
/// Draws a focus rectangle in the given bounds, if the item is focused. In Details View, if FullRowSelect is
/// true, the rectangle is drawn around the whole item, else around the first sub-item's text area.
/// </summary>
public void DrawFocusRectangle()
{
if ((State & ListViewItemStates.Focused) == ListViewItemStates.Focused)
{
ControlPaint.DrawFocusRectangle(Graphics, UpdateBounds(Bounds, drawText: false), Item.ForeColor, Item.BackColor);
}
}
/// <summary>
/// Draws the item's text (overloaded) - useful only when View != View.Details
/// </summary>
public void DrawText() => DrawText(TextFormatFlags.Left);
/// <summary>
/// Draws the item's text (overloaded) - useful only when View != View.Details - takes a TextFormatFlags argument.
/// </summary>
public void DrawText(TextFormatFlags flags)
{
TextRenderer.DrawText(Graphics, Item.Text, Item.Font, UpdateBounds(Bounds, drawText: true), Item.ForeColor, flags);
}
private Rectangle UpdateBounds(Rectangle originalBounds, bool drawText)
{
Rectangle resultBounds = originalBounds;
if (Item.ListView is not null && Item.ListView.View == View.Details)
{
// Note: this logic will compute the bounds so they align w/ the system drawn bounds only
// for the default font.
if (!Item.ListView.FullRowSelect && Item.SubItems.Count > 0)
{
ListViewItem.ListViewSubItem subItem = Item.SubItems[0];
Size textSize = TextRenderer.MeasureText(subItem.Text, subItem.Font);
resultBounds = new Rectangle(originalBounds.X, originalBounds.Y, textSize.Width, textSize.Height);
// Add some padding so we paint like the system control paints.
resultBounds.X += 4;
resultBounds.Width++;
}
else
{
resultBounds.X += 4;
resultBounds.Width -= 4;
}
if (drawText)
{
resultBounds.X--;
}
}
return resultBounds;
}
}
|