/// <summary> /// The workhorse to expand a threaded listview item /// </summary> /// <param name="lvItem"></param> /// <param name="activate">true, if lvItem should be activated</param> internal void ExpandListViewItem(ThreadedListViewItem lvItem, bool activate) { int selIdxsCount = SelectedIndices.Count; var selIdxs = new int[selIdxsCount]; SelectedIndices.CopyTo(selIdxs, 0); ThreadedListViewItem[] newItems; if (lvItem != null && lvItem.Collapsed) { if (RaiseBeforeExpandEventCancel(lvItem)) { lvItem.StateImageIndex = 0; // switch to non-state image (no +/-) return; } int paramItemIndex = lvItem.Index; int currentIndent = lvItem.IndentLevel; // if (base.SelectedItems.Count > 0 && activate) // selectedItemIndex = paramItemIndex; newItems = RaiseExpandEvent(lvItem); if (newItems == null) { ThreadedListViewItem item = _noChildsPlaceHolder; if (item == null) { item = new ThreadedListViewItemPlaceHolder(SR.FeedListNoChildsMessage) { Font = new Font(Font.FontFamily, Font.Size, FontStyle.Regular) }; } newItems = new[] { item }; } if (newItems.Length > 1 && ListViewItemSorter != null) { // sort new child entries according to listview sortorder Array.Sort(newItems, ListViewItemSorter); } if (_showInGroups) { APIEnableGrouping(false); } BeginUpdate(); try { lvItem.SetThreadState(true); lock (Items) { foreach (var newListItem in newItems) { // check, if we have all subitems for correct grouping while (newListItem.SubItems.Count < Columns.Count) { newListItem.SubItems.Add(String.Empty); } newListItem.Parent = lvItem; Items.Insert(paramItemIndex + 1, newListItem); newListItem.IndentLevel = currentIndent + 1; paramItemIndex++; } } } finally { EndUpdate(); } RedrawItems(); if (_showInGroups) { APIEnableGrouping(true); } // Make the last inserted subfolder visible, then the parent folder visible, // per default treeview behavior. try { EnsureVisible(paramItemIndex - 1); EnsureVisible(lvItem.Index); } catch (Exception ex) { _log.Error("EnsureVisible() failed", ex); } if (activate) { SelectedItems.Clear(); lvItem.Selected = true; lvItem.Focused = true; } else if (selIdxsCount > 0) { // foreach (int i in selIdxs) { // this.Items[i].Selected = true; // } } RaiseAfterExpandEvent(lvItem, newItems); } }
/// <summary> /// The workhorse to collapse a threaded listview item /// </summary> /// <param name="lvItem"></param> internal void CollapseListViewItem(ThreadedListViewItem lvItem) { if (lvItem != null && lvItem.Expanded) { if (RaiseBeforeCollapseEventCancel(lvItem)) { lvItem.StateImageIndex = 0; return; } int focusedItemIndex; if (FocusedItem == null) { focusedItemIndex = lvItem.Index; } else { focusedItemIndex = FocusedItem.Index; } BeginUpdate(); try { lvItem.SetThreadState(false); int paramItemIndex = lvItem.Index; int currentIndent = lvItem.IndentLevel; int nextIndex = paramItemIndex + 1; lock (Items) { while (nextIndex < base.Items.Count && ((ThreadedListViewItem)base.Items[nextIndex]).IndentLevel > currentIndent) { Items[nextIndex].Parent = null; Items.RemoveAt(nextIndex); if (nextIndex < focusedItemIndex) { focusedItemIndex = focusedItemIndex - 1; } else if (nextIndex == focusedItemIndex) { focusedItemIndex = paramItemIndex; } } } RaiseCollapseEvent(lvItem); } finally { EndUpdate(); } if (focusedItemIndex >= 0) { ListViewItem lvi = base.Items[focusedItemIndex]; lvi.Focused = true; lvi.Selected = true; } } }