C
campk
I have a question for anyone who might be able to help... I am in the
process of building a custom listview, and am dealing with sorting, and
wanting to use the asc/desc sort indicators in the column header... i
have tried setting the parent's SmallImageList property and using those
images as sort order indicators, but the ListView items also try to use
those images, which screw up the way the ListView renders in some
situations.
Drawing the column header is an easy enough way around this, but I am
running into trouble with dealing with the mouse over behaviour. I
attempt to access the MousePosition, and then test if the bounds of the
columnheader contain that point. This works just fine - however...
When you are moving from one column to another, from right to left
(this is the important part), the rightmost column (the one you just
came from) still evaluates the
e.Bounds.Contains(this.PoiintToClient(Control.MousePosition))
expression to 'True'...
Additionally, in the same Right to left motion, the columns' "hover"
seems to be off by one (delayed) as you mouse over...
So, if we have 4 columns {0,1,2,3} and we are moving Right to Left,
without leaving the vertical bounds of the ListView's column header...
If the mouse cursor is over column...
[3] --> [3] is "highlighted"
[2] --> [3] is "highlighted"
[1] --> [3] and [2] are "highlighted"
[0] --> [3] [2] [1] are all highlighted.
I don't understand entirely why this might be. Since it doesn't
exhibit any of this behaviour at all when you move over the columns
from Left to Right, I am guessing that the column header might
"virtually" extend all the way to the left, or something like that...
Is there a better way to determine whether or not the mouse is hovering
over the specific bounds of the column header?
Find the ColumnHeader OwnerDraw code below...
Thanks for any help you might be able to provide...
protected override void
OnDrawColumnHeader(DrawListViewColumnHeaderEventArgs e) {
e.DrawDefault = false;
Color normal = SystemColors.Control;
Color hover = SystemColors.ButtonHighlight;
Color hoverPress = Color.LightGreen;
Color normalBorder = SystemColors.InactiveBorder;
Color hoverBorder = Color.FromArgb(227,145,79);
Color verticalDiv = SystemColors.Highlight;
RectangleF txtRect = RectangleF.Empty;
Point mPoint = this.PointToClient(Control.MousePosition);
bool MouseHover = e.Bounds.Contains(mPoint);
Brush bgBrush;
if (MouseHover)
bgBrush = new SolidBrush(hover);
else
bgBrush = new SolidBrush(normal);
e.Graphics.FillRectangle(bgBrush, e.Bounds);
SizeF txtSize = e.Graphics.MeasureString(e.Header.Text, this.Font);
switch (e.Header.TextAlign) {
case HorizontalAlignment.Left:
txtRect = new RectangleF(
4 + e.Bounds.Left,
(e.Bounds.Height - txtSize.Height) / 2,
txtSize.Width,
txtSize.Height
);
break;
case HorizontalAlignment.Center:
txtRect = new RectangleF(
(e.Bounds.Width - txtSize.Width) / 2 + e.Bounds.Left,
(e.Bounds.Height - txtSize.Height) / 2,
txtSize.Width,
txtSize.Height
);
break;
case HorizontalAlignment.Right:
txtRect = new RectangleF(
(e.Bounds.Width - (e.Bounds.Width - txtSize.Width)) +
e.Bounds.Left,
(e.Bounds.Height - txtSize.Height) / 2,
txtSize.Width,
txtSize.Height
);
break;
}
e.Graphics.DrawString(e.Header.Text, this.Font, Brushes.Black,
txtRect);
Brush divBrush = new SolidBrush(SystemColors.Highlight);
Brush borderBrush = new SolidBrush(normalBorder);
//Draw the vertical divider if we aren't hovering
if (MouseHover)
borderBrush = new SolidBrush(hoverBorder);
if (!MouseHover)
e.Graphics.DrawLine(new Pen(divBrush, 1.25F), e.Bounds.Right - 2,
e.Bounds.Top + (0.20F * e.Bounds.Height), e.Bounds.Right - 2,
e.Bounds.Bottom - e.Bounds.Height / 3);
// draw bottom border
e.Graphics.DrawLine(new Pen(borderBrush, 2.0F), e.Bounds.Left,
e.Bounds.Bottom - 1, e.Bounds.Right, e.Bounds.Bottom - 1);
base.OnDrawColumnHeader(e);
}
process of building a custom listview, and am dealing with sorting, and
wanting to use the asc/desc sort indicators in the column header... i
have tried setting the parent's SmallImageList property and using those
images as sort order indicators, but the ListView items also try to use
those images, which screw up the way the ListView renders in some
situations.
Drawing the column header is an easy enough way around this, but I am
running into trouble with dealing with the mouse over behaviour. I
attempt to access the MousePosition, and then test if the bounds of the
columnheader contain that point. This works just fine - however...
When you are moving from one column to another, from right to left
(this is the important part), the rightmost column (the one you just
came from) still evaluates the
e.Bounds.Contains(this.PoiintToClient(Control.MousePosition))
expression to 'True'...
Additionally, in the same Right to left motion, the columns' "hover"
seems to be off by one (delayed) as you mouse over...
So, if we have 4 columns {0,1,2,3} and we are moving Right to Left,
without leaving the vertical bounds of the ListView's column header...
If the mouse cursor is over column...
[3] --> [3] is "highlighted"
[2] --> [3] is "highlighted"
[1] --> [3] and [2] are "highlighted"
[0] --> [3] [2] [1] are all highlighted.
I don't understand entirely why this might be. Since it doesn't
exhibit any of this behaviour at all when you move over the columns
from Left to Right, I am guessing that the column header might
"virtually" extend all the way to the left, or something like that...
Is there a better way to determine whether or not the mouse is hovering
over the specific bounds of the column header?
Find the ColumnHeader OwnerDraw code below...
Thanks for any help you might be able to provide...
protected override void
OnDrawColumnHeader(DrawListViewColumnHeaderEventArgs e) {
e.DrawDefault = false;
Color normal = SystemColors.Control;
Color hover = SystemColors.ButtonHighlight;
Color hoverPress = Color.LightGreen;
Color normalBorder = SystemColors.InactiveBorder;
Color hoverBorder = Color.FromArgb(227,145,79);
Color verticalDiv = SystemColors.Highlight;
RectangleF txtRect = RectangleF.Empty;
Point mPoint = this.PointToClient(Control.MousePosition);
bool MouseHover = e.Bounds.Contains(mPoint);
Brush bgBrush;
if (MouseHover)
bgBrush = new SolidBrush(hover);
else
bgBrush = new SolidBrush(normal);
e.Graphics.FillRectangle(bgBrush, e.Bounds);
SizeF txtSize = e.Graphics.MeasureString(e.Header.Text, this.Font);
switch (e.Header.TextAlign) {
case HorizontalAlignment.Left:
txtRect = new RectangleF(
4 + e.Bounds.Left,
(e.Bounds.Height - txtSize.Height) / 2,
txtSize.Width,
txtSize.Height
);
break;
case HorizontalAlignment.Center:
txtRect = new RectangleF(
(e.Bounds.Width - txtSize.Width) / 2 + e.Bounds.Left,
(e.Bounds.Height - txtSize.Height) / 2,
txtSize.Width,
txtSize.Height
);
break;
case HorizontalAlignment.Right:
txtRect = new RectangleF(
(e.Bounds.Width - (e.Bounds.Width - txtSize.Width)) +
e.Bounds.Left,
(e.Bounds.Height - txtSize.Height) / 2,
txtSize.Width,
txtSize.Height
);
break;
}
e.Graphics.DrawString(e.Header.Text, this.Font, Brushes.Black,
txtRect);
Brush divBrush = new SolidBrush(SystemColors.Highlight);
Brush borderBrush = new SolidBrush(normalBorder);
//Draw the vertical divider if we aren't hovering
if (MouseHover)
borderBrush = new SolidBrush(hoverBorder);
if (!MouseHover)
e.Graphics.DrawLine(new Pen(divBrush, 1.25F), e.Bounds.Right - 2,
e.Bounds.Top + (0.20F * e.Bounds.Height), e.Bounds.Right - 2,
e.Bounds.Bottom - e.Bounds.Height / 3);
// draw bottom border
e.Graphics.DrawLine(new Pen(borderBrush, 2.0F), e.Bounds.Left,
e.Bounds.Bottom - 1, e.Bounds.Right, e.Bounds.Bottom - 1);
base.OnDrawColumnHeader(e);
}