private void TreeControl_DoubleClick(object sender, DoubleClickEventArgs e) { VirtualTreeItemInfo itemInfo = e.ItemInfo; IItemFilter itemFilter; if (!itemInfo.Blank && null != (itemFilter = itemInfo.Branch as IItemFilter)) { PartitionChangeFilter filter = myFilter; bool filterWasClear = true; if (filter == null) { filter = new PartitionChangeFilter(); myFilter = filter; } else { filterWasClear = filter.IsClear; } itemFilter.FilterItem(filter, itemInfo.Row, itemInfo.Column); if (filter.FilterChanged) { (TreeControl.Tree.Root as ChangeBranch).FilterChanged(filter); if (filterWasClear != filter.IsClear) { if (filterWasClear) { ClearFilterButton.Enabled = true; CancelButton = ClearFilterButton; } else { ClearFilterButton.Enabled = false; CancelButton = CloseButton; } } e.Handled = true; } } }
private void TransactionLogViewer_FormClosed(object sender, FormClosedEventArgs e) { TreeControl.Tree = null; UndoItemsCombo.Items.Clear(); RedoItemsCombo.Items.Clear(); myRedoItems = null; myUndoItems = null; myFilter = null; }
private void ResetTree(TransactionItem transactionItem) { // MSBUG: We should be able to reset the Root branch with the // tree attached to the control, but it is losing subitem expansions // and causes all sorts of drawing problems, so detach and reattach // the tree. VirtualTreeControl control = TreeControl; ITree tree = control.Tree; control.Tree = null; myFilter = null; CancelButton = CloseButton; ClearFilterButton.Enabled = false; tree.Root = new ChangeBranch(transactionItem); control.MultiColumnTree = (IMultiColumnTree)tree; }
void IItemFilter.FilterItem(PartitionChangeFilter filter, int row, int column) { filter.DomainClass = myDomainClasses[row]; }
void IItemFilter.FilterItem(PartitionChangeFilter filter, int row, int column) { GenericEventArgs args; PartitionChange change = GetChange(row); switch ((ColumnContent)column) { case ColumnContent.Partition: Partition partition = change.Partition; if (partition != null) { filter.Partition = partition; } break; case ColumnContent.Model: DomainModelInfo model; if (null != (args = change.ChangeArgs as GenericEventArgs) && null != (model = args.DomainModel)) { DomainClassInfo baseDomainClass = RedirectDetailHandler.Instance.GetBaseDomainClassInfo(change); DomainModelInfo baseModelInfo; if (baseDomainClass != null && (baseModelInfo = baseDomainClass.DomainModel) != model) { model = baseModelInfo; } filter.DomainModel = model; } break; case ColumnContent.Class: DomainClassInfo classInfo; if (null != (args = change.ChangeArgs as GenericEventArgs) && null != (classInfo = args.DomainClass)) { filter.DomainClass = classInfo; } break; case ColumnContent.ChangeSource: if (null != (args = change.ChangeArgs as GenericEventArgs)) { filter.ChangeSource = args.ChangeSource; } break; case ColumnContent.Id: if (null != (args = change.ChangeArgs as GenericEventArgs)) { Guid id = args.ElementId; if (id != Guid.Empty) { filter.ElementId = id; } } break; case ColumnContent.ChangeType: filter.ChangeType = change.ChangeArgs.GetType(); break; case ColumnContent.Detail1: ElementPropertyChangedEventArgs propertyChangedArgs = change.ChangeArgs as ElementPropertyChangedEventArgs; if (null != propertyChangedArgs) { filter.DomainProperty = propertyChangedArgs.DomainProperty; } break; } }
void IItemFilter.FilterItem(PartitionChangeFilter filter, int row, int column) { if (row == 1) { filter.ElementId = myId; } }
void IItemFilter.FilterItem(PartitionChangeFilter filter, int row, int column) { switch (row) { case 1: filter.ElementId = myNewId; break; case 2: filter.ElementId = myOldId; break; } }
/// <summary> /// Called to potentially modify the current filter /// </summary> /// <param name="filter">The <see cref="PartitionChangeFilter"/></param> public void FilterChanged(PartitionChangeFilter filter) { int[] newFilter = null; int[] oldFilter = myFilter; if (oldFilter != null) { // We need to copy the filter because of the MSBUG with VirtualTree.DeleteItems discussed int filterCount = oldFilter.Length; newFilter = new int[filterCount]; oldFilter.CopyTo(newFilter, 0); } if (filter.ApplyFilter(myChanges, ref newFilter)) { int itemCount = VisibleItemCount; BranchModificationEventHandler modify = myModify; if (modify != null) { modify(this, BranchModificationEventArgs.DelayRedraw(true)); myFilter = newFilter; // This changes the VisibleItemCount int columnCount = (int)ColumnContent.Count; // MSBUG: VirtualTreeControl is not handling selection tracking // properly for some insert cases. So reducing the filter will work most // of the time, but anything with an insert (clearing the filter or changing // the filtered id) may end up with a random selection. There appear to be // two problems here. // 1) (Most common) VirtualTreeControl.ListBoxStateTracker.ApplyChange // is not processing absIndex == -1 for a positive count. This is the notification provided // when a new item is inserted before the current first item, so this is very bad. // 2) (Less common, but bad for us) Subitem changes are not being tracked correctly. I // have not tracked this one down fully, but it is likely in either the same routine // or VirtualTreeControl.OnToggleExpansion. // UNDONE: Work around selection tracking bug. // There should be two reliable workarounds: // 1) Support selection tracking so the control can snapshot the selection and // call VirtualTreeControl.SelectObject after the filter changes. // 2) Add our own OnItemCountChanged callback to calculate the correct selection // offsets and apply the selection change directly (probably more code, but also // a much more localized change. This might also help track down the problem // in the MS code) // Incrementally step through the change sets. Note that we must do this // carefully and in order because any callbacks for an insert/updatecellstyle must // be carefully coordinated to call back at the correct index in the filter. int fullItemCount = myChanges.Length; int oldItemNextIndex = 0; int oldFilterCount; int oldItem; if (oldFilter == null) { oldItem = 0; oldFilterCount = fullItemCount; } else { oldFilterCount = oldFilter.Length; oldItem = (oldFilterCount == 0) ? fullItemCount : oldFilter[oldItemNextIndex++]; } int newItemNextIndex = 0; int newFilterCount; int newItem; if (newFilter == null) { newItem = 0; newFilterCount = fullItemCount; } else { newFilterCount = newFilter.Length; newItem = (newFilterCount == 0) ? fullItemCount : newFilter[newItemNextIndex++]; } int nextIndex = 0; for (; ; ) { if (newItem == oldItem) { if (newItem == fullItemCount) { break; } newItem = (newFilter == null) ? (newItem + 1) : ((newItemNextIndex < newFilterCount) ? newFilter[newItemNextIndex++] : fullItemCount); oldItem = (oldFilter == null) ? (oldItem + 1) : ((oldItemNextIndex < oldFilterCount) ? oldFilter[oldItemNextIndex++] : fullItemCount); ++nextIndex; } else if (newItem < oldItem) { int startInsert = nextIndex; while (newItem < oldItem) { // Insert numbered item (newItem + 1) newItem = (newFilter == null) ? (newItem + 1) : ((newItemNextIndex < newFilterCount) ? newFilter[newItemNextIndex++] : fullItemCount); ++nextIndex; } // Insert indexed items: (startInsert + 1) through (nextIndex) // insert at startInsert with count nextIndex - startInsert modify(this, BranchModificationEventArgs.InsertItems(this, startInsert - 1, nextIndex - startInsert)); for (int i = 0; i < columnCount; ++i) { if (0 != (ColumnStyles(i) & SubItemCellStyles.Complex)) { for (int j = startInsert; j < nextIndex; ++j) { // MSBUG: Hack workaround a bug in VirtualTree.InsertItems. Inserting // a complex item should requery the branch for subitem expansions. // This isn't as severe as the other (it doesn't crash), but this should // still happen automatically. modify(this, BranchModificationEventArgs.UpdateCellStyle(this, j, i, true)); } } } } else // oldItem < newItem { int deleteBound = nextIndex; while (oldItem < newItem) { //Debug.WriteLine("Delete numbered item " + (oldItem + 1).ToString()); ++deleteBound; oldItem = (oldFilter == null) ? (oldItem + 1) : ((oldItemNextIndex < oldFilterCount) ? oldFilter[oldItemNextIndex++] : fullItemCount); } // Delete index items: (nextIndex) through (deleteBound - 1) // MSBUG: Hack workaround a bug in VirtualTree.DeleteItems. The // call to ChangeFullCountRecursive needs to pass a valid subItemIncr // instead of the constant value 0. for (int i = 0; i < columnCount; ++i) { if (0 != (ColumnStyles(i) & SubItemCellStyles.Complex)) { for (int j = nextIndex; j < deleteBound; ++j) { modify(this, BranchModificationEventArgs.UpdateCellStyle(this, j, i, false)); } } } modify(this, BranchModificationEventArgs.DeleteItems(this, nextIndex, deleteBound - nextIndex)); } } modify(this, BranchModificationEventArgs.DelayRedraw(false)); } } }