Skip to content

Commit 8a10cbd

Browse files
author
grammarian
committed
- Fix rendering so that OLVColumn.WordWrap works when using customised Renderers and when using the ListViewPrinter
git-svn-id: https://svn.code.sf.net/p/objectlistview/code/cs/trunk@836 0bec5ed8-b53f-49e6-9885-ce7bc93af311
1 parent 8d565dd commit 8a10cbd

File tree

4 files changed

+95
-62
lines changed

4 files changed

+95
-62
lines changed

Demo/TabComplexExample.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,7 @@ private void SetupDarkerStyle() {
296296
this.olvComplex.BackColor = Color.FromArgb(30, 30, 40);
297297
this.olvComplex.AlternateRowBackColor = Color.FromArgb(35, 35, 42);
298298
this.olvComplex.ForeColor = Color.WhiteSmoke;
299+
this.olvComplex.DefaultRenderer = new HighlightTextRenderer {FillBrush = Brushes.Transparent, FramePen = new Pen(Color.PaleGreen, 3)};
299300

300301
HyperlinkStyle hls = new HyperlinkStyle();
301302
hls.Normal = new CellStyle();

ListViewPrinter/ListViewPrinter.cs

Lines changed: 38 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
* Date: 2007-11-01 11:15 AM
66
*
77
* Change log:
8+
* 2018-10-06 JPP - Fix rendering so that OLVColumn.WordWrap works when using the ListViewPrinter
89
* 2009-02-24 JPP - Correctly use new renderer scheme :)
910
* 2009-01-26 JPP - Use new renderer scheme
1011
* - Removed ugly hack about BarRenderer when printing.
@@ -41,7 +42,7 @@
4142
*
4243
* To Do:
4344
*
44-
* Copyright (C) 2006-2008 Phillip Piper
45+
* Copyright (C) 2006-2018 Phillip Piper
4546
*
4647
* This program is free software: you can redistribute it and/or modify
4748
* it under the terms of the GNU General Public License as published by
@@ -1248,32 +1249,42 @@ protected override void PrintCell(Graphics g, ListView lv, ListViewItem lvi, int
12481249
return;
12491250
}
12501251

1251-
// Configure the renderer
1252-
renderer.IsPrinting = true;
1253-
renderer.Aspect = null;
1254-
renderer.Column = olvc;
1255-
renderer.IsItemSelected = false;
1256-
renderer.Font = this.CellFormat.Font;
1257-
renderer.TextBrush = this.CellFormat.TextBrush;
1258-
renderer.ListItem = olvItem;
1259-
renderer.ListView = listView;
1260-
renderer.RowObject = olvItem.RowObject;
1261-
renderer.SubItem = (OLVListSubItem)this.GetSubItem(lvi, column);
1262-
renderer.CanWrap = this.CellFormat.CanWrap;
1263-
1264-
// Use the cell block format to draw the background and border of the cell
1265-
bool bkChanged = this.ApplyCellSpecificBackground(this.CellFormat, renderer.ListItem, renderer.SubItem);
1266-
this.CellFormat.Draw(g, cell, "", "", "");
1267-
if (bkChanged)
1268-
this.CellFormat.BackgroundBrush = null;
1269-
1270-
// The renderer draws into the text area of the block. Unfortunately, the renderer uses Rectangle's
1271-
// rather than RectangleF's, so we have to convert, trying to prevent rounding errors
1272-
RectangleF r = this.CellFormat.CalculatePaddedTextBox(cell);
1273-
Rectangle r2 = new Rectangle((int)r.X + 1, (int)r.Y + 1, (int)r.Width - 1, (int)r.Height - 1);
1274-
renderer.Render(g, r2);
1275-
1276-
renderer.IsPrinting = false;
1252+
// Store renderer state
1253+
Font originalFont = renderer.Font;
1254+
bool? originalCanWrap = renderer.CanWrap;
1255+
1256+
try {
1257+
// Configure the renderer
1258+
renderer.IsPrinting = true;
1259+
renderer.Font = this.CellFormat.Font;
1260+
renderer.TextBrush = this.CellFormat.TextBrush;
1261+
renderer.CanWrap = this.CellFormat.CanWrap;
1262+
renderer.Aspect = null;
1263+
renderer.Column = olvc;
1264+
renderer.IsItemSelected = false;
1265+
renderer.ListItem = olvItem;
1266+
renderer.ListView = listView;
1267+
renderer.RowObject = olvItem.RowObject;
1268+
renderer.SubItem = (OLVListSubItem)this.GetSubItem(lvi, column);
1269+
1270+
// Use the cell block format to draw the background and border of the cell
1271+
bool bkChanged = this.ApplyCellSpecificBackground(this.CellFormat, renderer.ListItem, renderer.SubItem);
1272+
this.CellFormat.Draw(g, cell, "", "", "");
1273+
if (bkChanged)
1274+
this.CellFormat.BackgroundBrush = null;
1275+
1276+
// The renderer draws into the text area of the block. Unfortunately, the renderer uses Rectangle's
1277+
// rather than RectangleF's, so we have to convert, trying to prevent rounding errors
1278+
RectangleF r = this.CellFormat.CalculatePaddedTextBox(cell);
1279+
Rectangle r2 = new Rectangle((int)r.X + 1, (int)r.Y + 1, (int)r.Width - 1, (int)r.Height - 1);
1280+
renderer.Render(g, r2);
1281+
}
1282+
finally {
1283+
// Restore the original state
1284+
renderer.IsPrinting = false;
1285+
renderer.Font = originalFont;
1286+
renderer.CanWrap = originalCanWrap;
1287+
}
12771288
}
12781289
}
12791290

ObjectListView/OLVColumn.cs

Lines changed: 3 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1416,7 +1416,7 @@ public IList ValuesChosenForFiltering {
14161416
[Category("ObjectListView"),
14171417
Description("The width in pixels of this column"),
14181418
DefaultValue(60)]
1419-
new public int Width {
1419+
public new int Width {
14201420
get { return base.Width; }
14211421
set {
14221422
if (this.MaximumWidth != -1 && value > this.MaximumWidth)
@@ -1436,27 +1436,9 @@ public IList ValuesChosenForFiltering {
14361436
DefaultValue(false)]
14371437
public bool WordWrap {
14381438
get { return wordWrap; }
1439-
set {
1440-
wordWrap = value;
1441-
1442-
// If there isn't a renderer and they are turning word wrap off, we don't need to do anything
1443-
if (this.Renderer == null && !wordWrap)
1444-
return;
1445-
1446-
// All other cases require a renderer of some sort
1447-
if (this.Renderer == null)
1448-
this.Renderer = new HighlightTextRenderer();
1449-
1450-
BaseRenderer baseRenderer = this.Renderer as BaseRenderer;
1451-
1452-
// If there is a custom renderer (not descended from BaseRenderer),
1453-
// we leave it up to them to implement wrapping
1454-
if (baseRenderer == null)
1455-
return;
1456-
1457-
baseRenderer.CanWrap = wordWrap;
1458-
}
1439+
set { wordWrap = value; }
14591440
}
1441+
14601442
private bool wordWrap;
14611443

14621444
#endregion

ObjectListView/Rendering/Renderers.cs

Lines changed: 53 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
* Date: 27/09/2008 9:15 AM
66
*
77
* Change log:
8+
* 2018-10-06 JPP - Fix rendering so that OLVColumn.WordWrap works when using customised Renderers
89
* 2018-05-01 JPP - Use ITextMatchFilter interface rather than TextMatchFilter concrete class.
910
* v2.9.2
1011
* 2016-06-02 JPP - CalculateImageWidth() no longer adds 2 to the image width
@@ -279,20 +280,32 @@ public class BaseRenderer : AbstractRenderer {
279280
/// <summary>
280281
/// Can the renderer wrap lines that do not fit completely within the cell?
281282
/// </summary>
282-
/// <remarks>Wrapping text doesn't work with the GDI renderer.</remarks>
283+
/// <remarks>
284+
/// <para>If this is not set specifically, the value will be taken from Column.WordWrap</para>
285+
/// <para>
286+
/// Wrapping text doesn't work with the GDI renderer, so if this set to true, GDI+ rendering will used.
287+
/// The difference between GDI and GDI+ rendering can give word wrapped columns a slight different appearance.
288+
/// </para>
289+
/// </remarks>
283290
[Category("Appearance"),
284291
Description("Can the renderer wrap text that does not fit completely within the cell"),
285-
DefaultValue(false)]
286-
public bool CanWrap {
292+
DefaultValue(null)]
293+
public bool? CanWrap {
287294
get { return canWrap; }
288-
set {
289-
canWrap = value;
290-
if (canWrap)
291-
this.UseGdiTextRendering = false;
292-
}
295+
set { canWrap = value; }
293296
}
294-
private bool canWrap;
295297

298+
private bool? canWrap;
299+
300+
/// <summary>
301+
/// Get the actual value that should be used right now for CanWrap
302+
/// </summary>
303+
[Browsable(false)]
304+
protected bool CanWrapOrDefault {
305+
get {
306+
return this.CanWrap ?? this.Column != null && this.Column.WordWrap;
307+
}
308+
}
296309
/// <summary>
297310
/// Gets or sets how many pixels will be left blank around this cell
298311
/// </summary>
@@ -419,13 +432,15 @@ public int Spacing {
419432
/// Should text be rendered using GDI routines? This makes the text look more
420433
/// like a native List view control.
421434
/// </summary>
435+
/// <remarks>Even if this is set to true, it will return false if the renderer
436+
/// is set to word wrap, since GDI doesn't handle wrapping.</remarks>
422437
[Category("Appearance"),
423438
Description("Should text be rendered using GDI routines?"),
424439
DefaultValue(true)]
425440
public virtual bool UseGdiTextRendering {
426441
get {
427-
// Can't use GDI routines on a GDI+ printer context
428-
return !this.IsPrinting && useGdiTextRendering;
442+
// Can't use GDI routines on a GDI+ printer context or when word wrapping is required
443+
return !this.IsPrinting && !this.CanWrapOrDefault && useGdiTextRendering;
429444
}
430445
set { useGdiTextRendering = value; }
431446
}
@@ -502,6 +517,16 @@ public DrawListViewSubItemEventArgs Event {
502517
/// <summary>
503518
/// Gets or sets the font to be used for text in this cell
504519
/// </summary>
520+
/// <remarks>
521+
/// <para>
522+
/// In general, this property should be treated as internal.
523+
/// If you do set this, the given font will be used without any other consideration.
524+
/// All other factors -- selection state, hot item, hyperlinks -- will be ignored.
525+
/// </para>
526+
/// <para>
527+
/// A better way to set the font is to change either ListItem.Font or SubItem.Font
528+
/// </para>
529+
/// </remarks>
505530
[Browsable(false),
506531
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
507532
public Font Font {
@@ -622,6 +647,14 @@ public OLVListSubItem SubItem {
622647
/// <summary>
623648
/// The brush that will be used to paint the text
624649
/// </summary>
650+
/// <remarks>
651+
/// <para>
652+
/// In general, this property should be treated as internal. It will be reset after each render.
653+
/// </para>
654+
/// <para>
655+
/// </para>
656+
/// In particular, don't set it to configure the color of the text on the control. That should be done via SubItem.ForeColor
657+
/// </remarks>
625658
[Browsable(false),
626659
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
627660
public Brush TextBrush {
@@ -661,7 +694,6 @@ private void ClearState() {
661694
this.Event = null;
662695
this.DrawItemEvent = null;
663696
this.Aspect = null;
664-
this.Font = null;
665697
this.TextBrush = null;
666698
}
667699

@@ -1733,7 +1765,7 @@ protected virtual void DrawTextGdi(Graphics g, Rectangle r, String txt) {
17331765

17341766
// I think there is a bug in the TextRenderer. Setting or not setting SingleLine doesn't make
17351767
// any difference -- it is always single line.
1736-
if (!this.CanWrap)
1768+
if (!this.CanWrapOrDefault)
17371769
flags |= TextFormatFlags.SingleLine;
17381770
TextRenderer.DrawText(g, txt, this.Font, r, this.GetForegroundColor(), backColor, flags);
17391771
}
@@ -1770,7 +1802,7 @@ protected virtual StringFormat StringFormatForGdiPlus {
17701802
fmt.LineAlignment = this.EffectiveCellVerticalAlignment;
17711803
fmt.Trimming = StringTrimming.EllipsisCharacter;
17721804
fmt.Alignment = this.Column == null ? StringAlignment.Near : this.Column.TextStringAlign;
1773-
if (!this.CanWrap)
1805+
if (!this.CanWrapOrDefault)
17741806
fmt.FormatFlags = StringFormatFlags.NoWrap;
17751807
return fmt;
17761808
}
@@ -1816,6 +1848,13 @@ protected virtual void DrawTextGdiPlus(Graphics g, Rectangle r, String txt) {
18161848
/// <summary>
18171849
/// This renderer highlights substrings that match a given text filter.
18181850
/// </summary>
1851+
/// <remarks>
1852+
/// Implementation note:
1853+
/// This renderer uses the functionality of BaseRenderer to draw the text, and
1854+
/// then draws a translucent frame over the top of the already rendered text glyphs.
1855+
/// There's no way to draw the matching text in a different font or color in this
1856+
/// implementation.
1857+
/// </remarks>
18191858
public class HighlightTextRenderer : BaseRenderer, IFilterAwareRenderer {
18201859
#region Life and death
18211860

0 commit comments

Comments
 (0)