private void ShowVariableEditBox(string initialString) { // Only clicking on the top-most level item should bring up edit box. InspectionViewItem parent = ContainerFromItem(null, inspectionView.SelectedItem); if (null == parent || (0 != parent.Level)) { return; } currentEditingData = (InspectionData)inspectionView.SelectedItem; TextBlock nameBlock = FindDescendant <TextBlock>(parent); if (nameBlock != null) { txtVariableEditor.Height = nameBlock.Height; txtVariableEditor.Width = colName.Width; GeneralTransform transform = parent.TransformToAncestor(inspectionView); Point leftTopCoords = transform.Transform(new Point(0, 0)); if (string.IsNullOrEmpty(initialString)) { initialString = currentEditingData.DisplayText; } txtVariableEditor.Margin = new Thickness(2, leftTopCoords.Y, 0, 0); txtVariableEditor.Text = initialString; txtVariableEditor.Visibility = Visibility.Visible; txtVariableEditor.Focus(); txtVariableEditor.SelectAll(); } }
/// <summary> /// An 'Items.Refresh' call erases all the previous expansion data. This recursive /// method complements 'CheckExpansion' method where it does the expansion of items /// that were expanded before the refresh method closed them. /// </summary> /// <param name="dataVal"> /// The Observable Collection that holds all the data for the level below. /// Each InspectionData.Derivations is also an Observable Collection. /// </param> /// <param name="parent"> /// If parent is null, it means there is no parent and it is the top level data. /// Otherwise, send the parent item of the dataVal parameter /// </param> private void DoExpansion(ICollection <InspectionData> dataVal, InspectionViewItem parent = null) { if (dataVal == null) { return; } foreach (InspectionData item in dataVal) { if (parent != null) { parent.IsExpanded = true; parent.UpdateLayout(); } InspectionViewItem treeListViewItem = ContainerFromItem(parent, item); if (null == treeListViewItem) { return; } if (item.IsExpanded) { treeListViewItem.IsExpanded = true; } if (item.HasItems && item.IsExpanded) { DoExpansion(item.Derivations, treeListViewItem); } } }
private InspectionViewItem ContainerFromItem(InspectionViewItem parentItem, object item) { ItemContainerGenerator generator = inspectionView.ItemContainerGenerator; if (null != parentItem) { generator = parentItem.ItemContainerGenerator; } return(generator.ContainerFromItem(item) as InspectionViewItem); }
private void HideVariableEditBox(bool commitChanges, bool setFocusOnView) { if (null == currentEditingData) { return; // There's no editing item now. } if (currentEditingData.IsEmptyData == false) { Solution.Current.RemoveWatchExpressions(currentEditingData.Expression); } if (!string.IsNullOrEmpty(txtVariableEditor.Text) && (false != commitChanges)) { int index = dataCollection.GetParentIndex(currentEditingData); if (index >= 0 && index < dataCollection.Data.Count) { bool duplicateExpression = Solution.Current.AddWatchExpressions(txtVariableEditor.Text); if (duplicateExpression == true) { TextEditorControl.Instance.DisplayStatusMessage(StatusTypes.Info, Configurations.WatchWindowDuplicateInfo, 3); return; } dataCollection.UpdateVariableName(txtVariableEditor.Text, index); RefreshInspectionView(); } } InspectionViewItem viewItem = ContainerFromItem(null, currentEditingData); currentEditingData = null; if (null != viewItem) { viewItem.IsSelected = true; } txtVariableEditor.Visibility = Visibility.Hidden; UIElement elementToFocus = inspectionView; if (false != setFocusOnView) { elementToFocus = TextEditorControl.Instance.textCanvas; } elementToFocus.Focus(); }
private InspectionViewItem ContainerFromItem(InspectionData inspectionData) { List <InspectionData> reversedDataList = new List <InspectionData>(); InspectionData currentData = inspectionData; while (null != currentData) { reversedDataList.Insert(0, currentData); currentData = currentData.ParentData; } InspectionViewItem viewItem = null; foreach (InspectionData data in reversedDataList) { viewItem = ContainerFromItem(viewItem, data); } return(viewItem); }
/// <summary> /// This method checks all the items in the Watch window and takes note /// of what is expanded by toggling the 'isExpanded' flag in the InspectionData class. /// This information is later used by 'DoExpansion' to do the actual expansion /// </summary> /// <param name="dataVal"> /// The Observable Collection that holds all the data for the level below. /// Each InspectionData.Derivations is also an Observable Collection. /// </param> /// <param name="parent"> /// If parent is null, it means there is no parent and it is the top level data. /// Otherwise, send the parent item of the dataVal parameter /// </param> void UpdateExpansionStates(ICollection <InspectionData> dataVal, InspectionViewItem parent = null) { foreach (InspectionData item in dataVal) { if (item.IsEmptyData) { break; } InspectionViewItem treeListViewItem = ContainerFromItem(parent, item); if (null != treeListViewItem) { item.IsExpanded = treeListViewItem.IsExpanded; } if (item.HasItems && item.IsExpanded) { UpdateExpansionStates(item.Derivations, treeListViewItem); } } }
/// <summary> /// Event trigger when a keyboard button is pressed in the watch window /// </summary> /// <param name="sender"></param> /// <param name="e"> /// Keys accepted: /// Delete - to delete an item in the watch window /// Enter - to bring up the editing textbox for watch variables /// </param> private void OnWatchWindowKeyDown(object sender, KeyEventArgs e) { // Method to delete items from the watch window if (e.Key == Key.Delete) { InspectionData selectedData = inspectionView.SelectedItem as InspectionData; InspectionViewItem parent = ContainerFromItem(null, selectedData); if (null != parent && parent.Level == 0) { // Get the sibling item so that we can move selection on it later. InspectionData siblingData = GetSiblingItemFromData(selectedData); InspectionData removedItem = (InspectionData)inspectionView.SelectedItem; if (dataCollection.RemoveInspectionData(inspectionView.SelectedItem)) { Solution.Current.RemoveWatchExpressions(removedItem.DisplayText); inspectionView.Items.Refresh(); } // Set focus back to the item. InspectionViewItem siblingItem = ContainerFromItem(null, siblingData); if (null != siblingItem) { siblingItem.IsSelected = true; } } } // Method to allow user to bring up the editing textbox in the // watch window. This makes usage of watch window easy else if (e.Key == Key.Enter) { ShowVariableEditBox(null); } else if (e.Key >= Key.A && (e.Key <= Key.Z)) { char character = TextEditorControl.GetKeyboardCharacter(e); ShowVariableEditBox(new string(character, 1)); } }
/// <summary> /// Recursive method to iterate through all expanded items and return the expanded index value. Works in /// conjunction with the 'GetExpandedIndex' method /// </summary> /// <param name="dataVal"> /// The Observable Collection that holds all the data for the level below. /// Each InspectionData.Derivations is also an Observable Collection. /// </param> /// <param name="indexToCheck"> Parent index of the watch window expression </param> /// <param name="expandedIndex"> Out parameter, returning expanded index of the watch expression </param> /// <param name="parent"> /// If parent is null, it means there is no parent and it is the top level data. /// Otherwise, send the parent item of the dataVal parameter /// </param> private void ItemExpansionCount(ICollection <InspectionData> dataVal, int indexToCheck, ref int expandedIndex, TreeViewItem parent = null) { InspectionViewItem parentItem = parent as InspectionViewItem; foreach (InspectionData item in dataVal) { InspectionViewItem treeViewItem = ContainerFromItem(parentItem, item); if (treeViewItem.Level == 0) { if (dataCollection.GetParentIndex(item) == indexToCheck) { break; } } expandedIndex++; if (item.IsExpanded && item.HasItems) { ItemExpansionCount(item.Derivations, indexToCheck, ref expandedIndex, treeViewItem); } } }
/// <summary> /// 'Expander' is part of the toggle button defined in the XAML that shows the [+] or [-] /// sign when there are items under the current watch variable that can be inspected. /// To maximise efficiency, the expansion of items must happen only when the expander is clicked /// when showing [+]. This generated the child items from the Virtual Machine. /// </summary> /// <param name="sender"> The sender is the Toggle Button</param> /// <param name="e"></param> private void OnExpanderClicked(object sender, RoutedEventArgs e) { ToggleButton expanderToggle = (ToggleButton)sender; if (null == expanderToggle) { return; } // The parent we are trying to locate here is the InspectionViewItem. The // expander is buried beneath several layers of stackpanels and grids under the Item // and therefore we have to make numerous calls to find the InspectionViewItem. InspectionViewItem parent = (InspectionViewItem)VisualTreeHelper.GetParent (VisualTreeHelper.GetParent (VisualTreeHelper.GetParent (VisualTreeHelper.GetParent (VisualTreeHelper.GetParent (VisualTreeHelper.GetParent(expanderToggle)))))); object data = ((null == parent) ? null : parent.DataContext); InspectionData selectedData = data as InspectionData; if (null == selectedData) { return; } // expanderToggle.IsChecked == true means the [+] --> [-] if (expanderToggle.IsChecked == true) { parent.IsExpanded = false; dataCollection.ExpandInspection(selectedData); parent.IsExpanded = true; UpdateExpansionStates(); inspectionView.Items.Refresh(); DoExpansion(dataCollection.Data); #if false parent.IsExpanded = false; InspectionData selectedData = (InspectionData)parent.DataContext; dataCollection.ExpandInspection(selectedData); // If there is a large amount of data, the user may have to wait. // This is indicated by updating the mouse cursor. Mouse.SetCursor(Cursors.Wait); parent.IsSelected = true; parent.IsExpanded = true; selectedData.IsExpanded = true; UpdateExpansionStates(); inspectionView.Items.Refresh(); DoExpansion(dataCollection.Data); Mouse.SetCursor(Cursors.Arrow); #endif } // Select the item that is currently being expanded/collapsed. InspectionViewItem itemToSelect = ContainerFromItem(selectedData); if (null != itemToSelect) { itemToSelect.IsSelected = true; } }