SunnyUI.Net Based on C ා net WinForm open source control library, tool class library, extended class library and multi page development framework
- Blog: https://www.cnblogs.com/yhuse
- Gitee: https://gitee.com/yhuse/SunnyUI
- GitHub: https://github.com/yhuse/SunnyUI
- SunnyUI.Net List of articles
- Welcome to QQ group: 56829229 (sunny UI technology exchange group)
SunnyUI.Net Development log: ListBox add follow mouse over highlight
In QQ group, cunmu said that when ListBox mouse moves, the current line needs focus. I think about it. It's not hard to achieve it
Just redraw the Item when the mouse moves. Besides, the selected Item has changed its color.
See UIListBox Code:
protected override void OnDrawItem(DrawItemEventArgs e) { base.OnDrawItem(e); BeforeDrawItem?.Invoke(this, Items, e); if (Items.Count == 0) { return; } e.DrawBackground(); if (e.Index < 0 || e.Index >= Items.Count) { return; } StringFormat sStringFormat = new StringFormat(); sStringFormat.LineAlignment = StringAlignment.Center; Color backColor = (e.State & DrawItemState.Selected) == DrawItemState.Selected ? ItemSelectBackColor : BackColor; Color foreColor = (e.State & DrawItemState.Selected) == DrawItemState.Selected ? ItemSelectForeColor : ForeColor; Rectangle rect = new Rectangle(e.Bounds.X, e.Bounds.Y, e.Bounds.Width - 1, e.Bounds.Height - 1); e.Graphics.FillRectangle(BackColor, e.Bounds); e.Graphics.FillRoundRectangle(backColor, rect, 5); e.Graphics.DrawString(Items[e.Index].ToString(), e.Font, foreColor, e.Bounds, sStringFormat); }
Look: (e.state& DrawItemState.Selected ) == DrawItemState.Selected Select row status
See e.State has e.State== DrawItemState.HotLight , is not it highlighted? Then start to roll up the code and add the status judgment
Run
Dizziness... It hasn't changed. This HotLight doesn't work. OK, ask Du Niang...
Climb over mountains and rivers...
Find this: https://www.jb51.cc/csharp/101121.html
It refers to:
I use OwnerDrawFixed as a DrawMode in my WinForms application to customize the ListBox control. When a user hovers over a ListBoxItem, I want to redraw the background of the ListBoxItem (or do something else), that is, in MouseMove DrawItemState.HotLight Never for listbox, so I want to know how to simulate it and how to solve this problem
DrawItemState.HotLight Never for ListBox, always... Why is it so far...
Keep looking down:
resolvent
DrawItemState.HotLight Applies only to menus drawn by the owner, not to ListBox. For listbox, you must track items yourself:
public partial class Form1 : Form { private int _MouseIndex = -1; public Form1() { InitializeComponent(); } private void listBox1_DrawItem(object sender,DrawItemEventArgs e) { Brush textBrush = SystemBrushes.WindowText; if (e.Index > -1) { if (e.Index == _MouseIndex) { e.Graphics.FillRectangle(SystemBrushes.HotTrack,e.Bounds); textBrush = SystemBrushes.HighlightText; } else { if ((e.State & DrawItemState.Selected) == DrawItemState.Selected) { e.Graphics.FillRectangle(SystemBrushes.Highlight,e.Bounds); textBrush = SystemBrushes.HighlightText; } else e.Graphics.FillRectangle(SystemBrushes.Window,e.Bounds); } e.Graphics.DrawString(listBox1.Items[e.Index].ToString(),e.Font,textBrush,e.Bounds.Left + 2,e.Bounds.Top); } } private void listBox1_MouseMove(object sender,MouseEventArgs e) { int index = listBox1.IndexFromPoint(e.Location); if (index != _MouseIndex) { _MouseIndex = index; listBox1.Invalidate(); } } private void listBox1_MouseLeave(object sender,EventArgs e) { if (_MouseIndex > -1) { _MouseIndex = -1; listBox1.Invalidate(); } } }
Brothers, what they have spent two years to solve should be useful. Continue to look for it and find another one in a foreign language:
https://stackoverflow.com/questions/1316027/listbox-drawitem-hotlight-state-in-the-ownerdraw-mode
It took me only two years to find the answer for you, but here it is:
The DrawItemState.HotLight only applies to owner drawn menus, not the listbox.
For the ListBox, you have to keep track of the item yourself:
Look, it's also two years. It's estimated that the above Chinese translation came from this.
Besides these two, I haven't found them.
Continue to roll up the code, it really works. However, there is still a problem. The mouse slides fast and the ListBox blinks badly.
Parse code listBox1.Invalidate(); this is refreshing all. Mouse over is also related to this selection and the last selection.
Just swipe these two items. If you have an idea, you can send them three times in a row:
private int lastIndex = -1; private int mouseIndex = -1; [Browsable(false)] public int MouseIndex { get => mouseIndex; set { if (mouseIndex != value) { if (lastIndex >= 0 && lastIndex != SelectedIndex) { OnDrawItem(new DrawItemEventArgs(this.CreateGraphics(), Font, GetItemRectangle(lastIndex), lastIndex, DrawItemState.Grayed)); } mouseIndex = value; if (mouseIndex >= 0 && mouseIndex != SelectedIndex) { OnDrawItem(new DrawItemEventArgs(this.CreateGraphics(), Font, GetItemRectangle(value), value, DrawItemState.HotLight)); } lastIndex = mouseIndex; } } } protected override void OnMouseMove(MouseEventArgs e) { base.OnMouseMove(e); MouseIndex = IndexFromPoint(e.Location); } protected override void OnMouseLeave(EventArgs e) { base.OnMouseLeave(e); MouseIndex = -1; }
Where new drawitemeventargs( this.CreateGraphics (), Font, GetItemRectangle(value), value, DrawItemState.HotLight )
The first parameter, Graphics, was also found for a while. Later, see this:
https://www.cnblogs.com/yuanyeguhong/archive/2013/09/20/3330606.html
In fact, it is the DrawString method of the Graphics object, and how does the Graphics in the parameter e come from.
We then analyze the DrawItemEventArgs class. Since it is a package of listBox1 properties,
So I guess the Graphics object is from listbox1.creategraphics.
OK, now we can customize the function of redrawing listbox, which can be called at will!
OK, so far, we have found the answers to all the questions, and then we need to straighten out our thinking and put the logic in order. Roll code, debug, OK!!!
The main codes are as follows:
protected override void OnDrawItem(DrawItemEventArgs e) { base.OnDrawItem(e); BeforeDrawItem?.Invoke(this, Items, e); if (Items.Count == 0) { return; } bool otherState = e.State == DrawItemState.Grayed || e.State == DrawItemState.HotLight; if (!otherState) { e.DrawBackground(); } if (e.Index < 0 || e.Index >= Items.Count) { return; } StringFormat sStringFormat = new StringFormat(); sStringFormat.LineAlignment = StringAlignment.Center; bool isSelected = (e.State & DrawItemState.Selected) == DrawItemState.Selected; Color backColor = isSelected ? ItemSelectBackColor : BackColor; Color foreColor = isSelected ? ItemSelectForeColor : ForeColor; Rectangle rect = new Rectangle(e.Bounds.X, e.Bounds.Y, e.Bounds.Width - 1, e.Bounds.Height - 1); if (!otherState) { e.Graphics.FillRectangle(BackColor, e.Bounds); e.Graphics.FillRoundRectangle(backColor, rect, 5); e.Graphics.DrawString(Items[e.Index].ToString(), e.Font, foreColor, e.Bounds, sStringFormat); } else { if (e.State == DrawItemState.Grayed) { backColor = BackColor; foreColor = ForeColor; } if (e.State == DrawItemState.HotLight) { backColor = HoverColor; foreColor = ForeColor; } e.Graphics.FillRectangle(BackColor, e.Bounds); e.Graphics.FillRoundRectangle(backColor, rect, 5); e.Graphics.DrawString(Items[e.Index].ToString(), e.Font, foreColor, e.Bounds, sStringFormat); } AfterDrawItem?.Invoke(this, Items, e); }
Look, DrawItemState.HotLight We have achieved it, DrawItemState.Grayed I am in a state of random choice, different from others.
Want to see all the code, see my open source project, https://gitee.com/yhuse/SunnyUI Hey, sir, don't go away. Order a Star first.