📄 treelistview.cs
字号:
if(_selectionMark.Parent == item.Parent &&
((APIsEnums.KeyStatesMasks)(int)m.WParam & APIsEnums.KeyStatesMasks.SHIFT) == APIsEnums.KeyStatesMasks.SHIFT)
{
_updating = true;
SetSelectedItemsRange(item, _selectionMark);
// Prevent all item at the wrong level of being selected
m.WParam = (IntPtr) APIsEnums.KeyStatesMasks.CONTROL;
base.WndProc(ref m);
item.Selected = true;
_updating = false;
DrawSelectedItemsFocusCues();
return;
}
}
break;
#endregion
#region LBUTTONDBLCLK
// Disable this notification to remove the auto-check when
// the user double-click on an item and append the expand / collapse function
case APIsEnums.WindowMessages.LBUTTONDBLCLK:
_lastdoubleclick = DateTime.Now;
if(FocusedItem != null)
{
item = FocusedItem;
bool doExpColl = false;
switch(ExpandMethod)
{
case TreeListViewExpandMethod.IconDbleClick:
rec = item.GetBounds(ItemBoundsPortion.Icon);
if(rec.Contains(PointToClient(MousePosition))) doExpColl = true;
break;
case TreeListViewExpandMethod.ItemOnlyDbleClick:
rec = item.GetBounds(ItemBoundsPortion.ItemOnly);
if(rec.Contains(PointToClient(MousePosition))) doExpColl = true;
break;
case TreeListViewExpandMethod.EntireItemDbleClick:
rec = item.GetBounds(ItemBoundsPortion.Entire);
if(rec.Contains(PointToClient(MousePosition))) doExpColl = true;
break;
default:
break;
}
if(doExpColl)
{
_dblclicktime = DateTime.Now;
Cursor = Cursors.WaitCursor;
BeginUpdate();
if(item.IsExpanded) item.Collapse();
else item.Expand();
EndUpdate();
Cursor = Cursors.Default;
}
}
OnDoubleClick(new EventArgs());
return;
#endregion
#region MOUSEMOVE
case APIsEnums.WindowMessages.MOUSEMOVE:
if((MouseButtons & MouseButtons.Left) != MouseButtons.Left && HasMarquee)
_hasMarquee = false;
break;
#endregion
#region UNICHAR, CHAR, KEYDOWN
case APIsEnums.WindowMessages.UNICHAR:
case APIsEnums.WindowMessages.CHAR:
CharPressed((char) m.WParam);
return;
case APIsEnums.WindowMessages.KEYDOWN:
OnKeyDown(new KeyEventArgs((Keys)(int) m.WParam));
return;
#endregion
#region PAINT
case APIsEnums.WindowMessages.PAINT:
if(InEdit && EditedItem.Item != null)
{
APIsStructs.RECT rect = new APIsStructs.RECT(
EditedItem.Item.GetBounds(ItemBoundsPortion.Entire));
APIsUser32.ValidateRect(Handle, ref rect);
}
base.WndProc(ref m);
DrawIntermediateStateItems();
DrawSelectedItemsFocusCues();
return;
#endregion
#region VSCROLL, HSCROLL, ENSUREVISIBLE
case APIsEnums.WindowMessages.VSCROLL:
case APIsEnums.WindowMessages.HSCROLL:
case (APIsEnums.WindowMessages)APIsEnums.ListViewMessages.ENSUREVISIBLE:
if(!Scrollable)
{
m.Result = (IntPtr)0;
return;
}
break;
#endregion
}
base.WndProc(ref m);
}
#region KeyFunction
#region OnKeyDown
/// <summary>
/// Raises the KeyDown event
/// </summary>
/// <param name="e"></param>
protected override void OnKeyDown(KeyEventArgs e)
{
Keys key = e.KeyCode;
if(FocusedItem == null)
{
if(base.Items.Count > 0 &&
(key == Keys.Down || key == Keys.Up || key == Keys.Left || key == Keys.Right))
{
base.Items[0].Selected = true;
base.Items[0].Focused = true;
base.Items[0].EnsureVisible();
}
base.OnKeyDown(e);
return;
}
TreeListViewItem item = FocusedItem;
switch(key)
{
case Keys.Down:
if(item.NextVisibleItem != null)
{
TreeListViewItem nextitem = item.NextVisibleItem;
if((Control.ModifierKeys & Keys.Shift) == Keys.Shift &&
MultiSelect)
{
if(item.Parent != nextitem.Parent && item.Selected)
{
while((nextitem = nextitem.NextVisibleItem) != null)
if(nextitem.Parent == item.Parent)
break;
}
if(nextitem != null)
SetSelectedItemsRange(_selectionMark, nextitem);
else
nextitem = item.NextVisibleItem;
}
else if((Control.ModifierKeys & Keys.Control) != Keys.Control)
{
SetSelectedItemsRange(nextitem, nextitem);
_selectionMark = nextitem;
}
nextitem.Focused = true;
nextitem.EnsureVisible();
}
break;
case Keys.Up:
if(item.PrevVisibleItem != null)
{
TreeListViewItem previtem = item.PrevVisibleItem;
if((Control.ModifierKeys & Keys.Shift) == Keys.Shift &&
MultiSelect)
{
if(item.Parent != previtem.Parent && item.Selected)
{
while((previtem = previtem.PrevVisibleItem) != null)
if(previtem.Parent == item.Parent)
break;
}
if(previtem != null)
SetSelectedItemsRange(_selectionMark, previtem);
else
previtem = item.PrevVisibleItem;
}
else if((Control.ModifierKeys & Keys.Control) != Keys.Control)
{
SetSelectedItemsRange(previtem, previtem);
_selectionMark = previtem;
}
previtem.Focused = true;
previtem.EnsureVisible();
}
break;
case Keys.Enter:
base.SelectedItems.Clear();
if(item.IsExpanded) item.Collapse();
else item.Expand();
item.Selected = true;
item.EnsureVisible();
break;
case Keys.Left:
if(item.IsExpanded)
{
base.SelectedItems.Clear();
item.Selected = true;
item.Collapse();
item.EnsureVisible();
}
else if(item.Parent != null)
{
base.SelectedItems.Clear();
item.Parent.Selected = true;
item.Parent.Focused = true;
item.Parent.EnsureVisible();
}
break;
case Keys.Right:
if(item.Items.Count == 0) break;
if(!item.IsExpanded)
{
base.SelectedItems.Clear();
item.Selected = true;
item.Expand();
item.EnsureVisible();
}
else
{
base.SelectedItems.Clear();
item.Items[item.Items.Count-1].Selected = true;
item.Items[item.Items.Count-1].Focused = true;
item.Items[item.Items.Count-1].EnsureVisible();
}
break;
case Keys.Space:
if(base.CheckBoxes) item.Checked = !item.Checked;
break;
}
base.OnKeyDown(e);
}
#endregion
#region CharPressed
private void CharPressed(char character)
{
Debug.Assert(!InvokeRequired);
string begin = character.ToString().ToUpper();
if(FocusedItem == null) return;
TreeListViewItem item = FocusedItem;
base.SelectedItems.Clear();
item.Selected = true;
// Select an item begining with the specified character
if((begin.CompareTo("A") >= 0 && begin.CompareTo("Z") <= 0) || begin == " ")
{
// Get the collection in wich the item is
TreeListViewItemCollection collection = item.Parent == null ? this.Items : item.Parent.Items;
bool founded = false;
// Search in the next items
for(int i = collection.GetIndexOf(item) + 1 ; i < collection.Count ; i++)
if(collection[i].Text.ToUpper().StartsWith(begin))
{
collection[i].Selected = true;
collection[i].Focused = true;
collection[i].EnsureVisible();
founded = true;
break;
}
// Search in the previous items
if(!founded)
for(int i = 0 ; i < collection.GetIndexOf(item) ; i++)
if(collection[i].Text.ToUpper().StartsWith(begin))
{
collection[i].Selected = true;
collection[i].Focused = true;
collection[i].EnsureVisible();
founded = true;
break;
}
}
}
#endregion
#endregion
#endregion
#region Draw
#region CustomDraw
private void CustomDraw(ref Message m)
{
int iRow, iCol; bool bSelected;
unsafe
{
APIsStructs.NMLVCUSTOMDRAW * nmlvcd = (APIsStructs.NMLVCUSTOMDRAW *)m.LParam.ToPointer();
switch((APIsEnums.CustomDrawDrawStateFlags)nmlvcd->nmcd.dwDrawStage)
{
case APIsEnums.CustomDrawDrawStateFlags.PREPAINT:
m.Result = (IntPtr)APIsEnums.CustomDrawReturnFlags.NOTIFYITEMDRAW;
break;
case APIsEnums.CustomDrawDrawStateFlags.ITEMPREPAINT:
m.Result = (IntPtr)APIsEnums.CustomDrawReturnFlags.NOTIFYSUBITEMDRAW;
break;
case APIsEnums.CustomDrawDrawStateFlags.ITEMPREPAINT |
APIsEnums.CustomDrawDrawStateFlags.SUBITEM:
iRow = (int)nmlvcd->nmcd.dwItemSpec;
iCol = (int)nmlvcd->iSubItem;
bSelected = base.Items[iRow].Selected;// && this.Focused;
TreeListViewItem item = GetTreeListViewItemFromIndex(iRow);
if(bSelected && _useXPHighLightStyle)
{
Color color = Focused ? ColorUtil.VSNetSelectionColor : ColorUtil.VSNetSelectionUnfocusedColor;
if(HideSelection && !Focused) color = BackColor;
if(FullRowSelect || iCol == 0)
nmlvcd->clrTextBk = (int)ColorUtil.RGB(color.R, color.G, color.B);
nmlvcd->nmcd.uItemState &= ~(uint)APIsEnums.CustomDrawItemStateFlags.SELECTED;
if(iCol == 0) item.DrawFocusCues();
}
if(iCol == 0)
{
item.DrawIntermediateState();
item.DrawPlusMinusLines();
item.DrawPlusMinus();
}
m.Result = (IntPtr)APIsEnums.CustomDrawReturnFlags.NEWFONT;
break;
}
}
}
#endregion
#region Draw Items Parts
internal void DrawIntermediateStateItems()
{
Debug.Assert(!InvokeRequired);
if(CheckBoxes != CheckBoxesTypes.Recursive) return;
if(_updating) return;
TreeListViewItemCollection items = GetVisibleItems();
Graphics g = Graphics.FromHwnd(Handle);
foreach(TreeListViewItem item in items)
item.DrawIntermediateState(g);
g.Dispose();
}
internal void DrawSelectedItemsFocusCues()
{
if(_updating) return;
if((HideSelection && !Focused) || !_useXPHighLightStyle) return;
Debug.Assert(!InvokeRequired);
SelectedTreeListViewItemCollection items = SelectedItems;
if(FocusedItem != null && Focused)
FocusedItem.DrawFocusCues();
foreach(TreeListViewItem temp in items)
temp.DrawFocusCues();
}
internal void DrawPlusMinusItems()
{
if(_updating) return;
Graphics g = Graphics.FromHwnd(Handle);
TreeListViewItemCollection items = GetVisibleItems();
foreach(TreeListViewItem item in items)
item.DrawPlusMinus(g);
g.Dispose();
}
internal void DrawPlusMinusItemsLines()
{
if(_updating) return;
Graphics g = Graphics.FromHwnd(Handle);
TreeListViewItemCollection items = GetVisibleItems();
foreach(TreeListViewItem item in items)
item.DrawPlusMinusLines(g);
g.Dispose();
}
#endregion
#endregion
#region Functions
#region SetSelectedItemsRange
private void SetSelectedItemsRange(TreeListViewItem item1, TreeListViewItem item2)
{
if(InvokeRequired)
throw(new Exception("Invoke required"));
if(item1 == null || item2 == null) return;
if(!item1.Visible || !item2.Visible) return;
if(item1.Parent != item2.Parent) return;
TreeListViewItemCollection items = item1.Container;
int index1 = items.GetIndexOf(item1);
int index2 = items.GetIndexOf(item2);
ListViewItem[] selItems = new ListViewItem[base.SelectedItems.Count];
base.SelectedItems.CopyTo(selItems, 0);
foreach(ListViewItem selItem in selItems)
{
int selItemIndex = items.GetIndexOf((TreeListViewItem)selItem);
if(selItemIndex < Math.Min(index1, index2) ||
selItemIndex > Math.Max(index1, index2))
selItem.Selected = false;
}
for(int i = Math.Min(index1, index2); i <= Math.Max(index1, index2); i++)
if(!items[i].Selected) items[i].Selected = true;
}
#endregion
#region ExpandAll / CollapseAll
/// <summary>
/// Expands all the tree nodes
/// </summary>
public void ExpandAll()
{
if(InvokeRequired)
throw(new Exception("Invoke required"));
BeginUpdate();
foreach(TreeListViewItem item in Items)
item.ExpandAllInternal();
EndUpdate();
}
/// <summary>
/// Collapses all the tree nodes
/// </summary>
public void CollapseAll()
{
if(InvokeRequired)
throw(new Exception("Invoke required"));
BeginUpdate();
foreach(TreeListViewItem item in Items)
item.CollapseAllInternal();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -