예제 #1
0
        private IEnumerable <RootNodeCategoryViewModel> CategorizeEntries(IEnumerable <NodeSearchElement> entries, bool expanded)
        {
            var tempRoot = entries.GroupByRecursive <NodeSearchElement, string, NodeCategoryViewModel>(
                element => element.Categories,
                (name, subs, es) =>
            {
                var category =
                    new NodeCategoryViewModel(name, es.OrderBy(en => en.Name).Select(MakeNodeSearchElementVM), subs);
                category.IsExpanded                  = expanded;
                category.RequestBitmapSource        += SearchViewModelRequestBitmapSource;
                category.RequestReturnFocusToSearch += OnRequestFocusSearch;
                return(category);
            }, "");

            var result = tempRoot.SubCategories.Select(cat =>
            {
                var rootCat = new RootNodeCategoryViewModel(cat.Name, cat.Entries, cat.SubCategories)
                {
                    IsExpanded = expanded
                };

                rootCat.RequestReturnFocusToSearch += OnRequestFocusSearch;
                return(rootCat);
            });

            tempRoot.Dispose();
            return(result.OrderBy(cat => cat.Name));
        }
예제 #2
0
        private IEnumerable <RootNodeCategoryViewModel> CategorizeEntries(IEnumerable <NodeSearchElement> entries, bool expanded)
        {
            var tempRoot = entries.GroupByRecursive <NodeSearchElement, string, NodeCategoryViewModel>(
                element => element.Categories,
                (name, subs, es) =>
            {
                var category =
                    new NodeCategoryViewModel(name, es.OrderBy(en => en.Name).Select(MakeNodeSearchElementVM), subs);
                category.IsExpanded                  = expanded;
                category.RequestBitmapSource        += SearchViewModelRequestBitmapSource;
                category.RequestReturnFocusToSearch += OnRequestFocusSearch;
                return(category);
            }, "");

            var result = tempRoot.SubCategories.Select(cat =>
            {
                var rootCat = new RootNodeCategoryViewModel(cat.Name, cat.Entries, cat.SubCategories)
                {
                    IsExpanded = expanded
                };

                rootCat.RequestReturnFocusToSearch += OnRequestFocusSearch;
                // Since all the root categories will be new RootNodeCategoryViewModel objects,
                // we should dispose the old ones. Since they are still watching for subcategories'
                // property changes, they will never be garbage collected.
                cat.Dispose();
                return(rootCat);
            });

            tempRoot.Dispose();
            return(result.OrderBy(cat => cat.Name));
        }
예제 #3
0
        internal bool MakeOrClearSelection(NodeCategoryViewModel selectedClass)
        {
            if (currentClass != null)
            {
                if (currentClass != selectedClass)
                {
                    // If 'itemIndex' is '-1', then the selection will be cleared,
                    // otherwise the selection is set to the same as 'itemIndex'.
                    var itemIndex = collection.IndexOf(selectedClass);
                    classListView.SelectedIndex = itemIndex;
                    return(true); // The call is handled.
                }
                else
                {
                    // If current item is selected item, then class button was pressed second time.
                    // Selection should be cleaned.
                    classListView.SelectedIndex = -1;
                    return(true);
                }
            }
            else
            {
                // No selection, if item is within collection, select it.
                var itemIndex = collection.IndexOf(selectedClass);
                if (itemIndex != -1)
                {
                    classListView.SelectedIndex = itemIndex;
                    return(true); // The call is handled.
                }
            }

            // The call is not handled.
            return(false);
        }
예제 #4
0
        public void BrowserInternalElementToBoolConverterTest()
        {
            var    converter = new NodeCategoryVMToBoolConverter();
            var    NcVM      = new NodeCategoryViewModel("");
            var    RncVM     = new RootNodeCategoryViewModel("");
            var    CncVM     = new ClassesNodeCategoryViewModel(RncVM);
            object result;

            //1. Element is null.
            //2. Element is NodeCategoryViewModel.
            //2. Element is RootNodeCategoryViewModel.
            //2. Element is ClassesNodeCategoryViewModel.

            // 1 case
            result = converter.Convert(null, null, null, null);
            Assert.AreEqual(false, result);

            // 2 case
            result = converter.Convert(NcVM, null, null, null);
            Assert.AreEqual(true, result);

            // 3 case
            result = converter.Convert(RncVM, null, null, null);
            Assert.AreEqual(false, result);

            // 4 case
            result = converter.Convert(CncVM, null, null, null);
            Assert.AreEqual(false, result);
        }
예제 #5
0
        private static NodeCategoryViewModel GetCategoryViewModel(NodeCategoryViewModel rootCategory,
                                                                  IEnumerable <string> categories)
        {
            var nameStack = new Stack <string>(categories.Reverse());
            NodeCategoryViewModel target     = rootCategory;
            NodeCategoryViewModel newTarget  = null;
            bool isCheckedForClassesCategory = false;

            while (nameStack.Any())
            {
                var currentCategory = nameStack.Pop();
                newTarget = target.SubCategories.FirstOrDefault(c => c.Name == currentCategory);
                if (newTarget == null)
                {
                    if (!isCheckedForClassesCategory && !target.IsClassButton &&
                        target.SubCategories[0] is ClassesNodeCategoryViewModel)
                    {
                        isCheckedForClassesCategory = true;
                        nameStack.Push(currentCategory);
                        nameStack.Push(Configurations.ClassesDefaultName);
                        continue;
                    }

                    return(null);
                }

                target = newTarget;
            }

            return(target);
        }
예제 #6
0
        // TODO: classes functionality.
        internal void AddClassToGroup(NodeCategoryViewModel memberNode)
        {
            // TODO: The following limit of displaying only two classes are
            // temporary, it should be updated whenever the design intent has been finalized.
            // http://adsk-oss.myjetbrains.com/youtrack/issue/MAGN-6199

            //const int maxClassesCount = 2;
            //if (classes.Count >= maxClassesCount)
            //    return;

            // Parent should be of 'BrowserInternalElement' type or derived.
            // Root category can't be added to classes list.
            // TODO(Vladimir): Implement the logic when classes are shown in search results.
        }
예제 #7
0
        private static void PlaceInNewCategory(
            NodeSearchElementViewModel entry, NodeCategoryViewModel target,
            IEnumerable <string> categoryNames)
        {
            var newTargets =
                categoryNames.Select(name => new NodeCategoryViewModel(name));

            foreach (var newTarget in newTargets)
            {
                target.SubCategories.Add(newTarget);
                target = newTarget;
            }

            target.Entries.Add(entry);
        }
예제 #8
0
 private void AddEntryToExistingCategory(NodeCategoryViewModel category,
                                         NodeSearchElementViewModel entry)
 {
     category.RequestBitmapSource += SearchViewModelRequestBitmapSource;
     // Check if the category exists already.
     // ex : clockwork package. For clockwork
     // package the category names in dyf is different from what we show it
     // on the tree view. so when you click on the category to populate it
     // triggers an update to category name. on the same instance when you uninstall
     // and insall the clockwork package, the categories are named correctly but
     // every install triggers an update that gives a duplicate entry. so check if the
     // entry is already added (specific to browse).
     if (category.Entries.All(x => x.FullName != entry.FullName))
     {
         category.Entries.Add(entry);
     }
 }
예제 #9
0
        public void LibraryTreeItemsHostVisibilityConverterTest()
        {
            var converter = new LibraryTreeItemsHostVisibilityConverter();

            var result = converter.Convert(null, null, null, null);

            Assert.AreEqual(Visibility.Visible, result);

            var NcVM = new NodeCategoryViewModel("");

            result = converter.Convert(NcVM, null, null, null);
            Assert.AreEqual(Visibility.Visible, result);

            var RncVM = new ClassesNodeCategoryViewModel(NcVM);

            result = converter.Convert(RncVM, null, null, null);
            Assert.AreEqual(Visibility.Collapsed, result);
        }
예제 #10
0
        private void ExpandCategory(TreeViewItem sender, NodeCategoryViewModel selectedClass)
        {
            // Get all category items.
            var categories = sender.Items.OfType <NodeCategoryViewModel>();

            // Get all current expanded categories.
            List <NodeCategoryViewModel> allExpandedCategories = categories.
                                                                 Where(cat => (!(cat is ClassesNodeCategoryViewModel) && cat.IsExpanded == true)).ToList();

            var categoryToBeExpanded = categories.Where(cat => cat == selectedClass).FirstOrDefault();

            // If categoryToBeExpanded is null, that means not category button, but class button was clicked.
            // During loop we will find out to which category this clicked class belongs.
            if (categoryToBeExpanded != null)
            {
                categoryToBeExpanded.IsExpanded = !categoryToBeExpanded.IsExpanded;
            }

            // Get expanded categories that should be collapsed.
            var categoriesToBeCollapsed = allExpandedCategories.Remove(categoryToBeExpanded);

            // Close all open categories, except one, that contains class.
            // Or if category was clicked, also expand it and close others.
            foreach (var categoryToBeCollapsed in allExpandedCategories)
            {
                // If class button was clicked.
                if (categoryToBeExpanded == null)
                {
                    var categoryClasses = categoryToBeCollapsed.Items[0] as ClassesNodeCategoryViewModel;
                    // Ensure, that this class is not part of current category.
                    if (categoryClasses != null)
                    {
                        categoryToBeCollapsed.IsExpanded = categoryClasses.Items.Contains(selectedClass);
                    }
                }
                // If category button was clicked.
                else
                {
                    categoryToBeCollapsed.IsExpanded = false;
                }
            }
        }
예제 #11
0
        private void OnClassViewSelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            var selectedIndex = (sender as ListView).SelectedIndex;

            // As focus moves within the class details, class button gets selected which
            // triggers a selection change. During a selection change the items in the
            // wrap panel gets reordered through "OrderListItems", but this is not always
            // necessary. Here we determine if the "translatedIndex" is the same as
            // "selectedClassProspectiveIndex", if so simply returns to avoid a repainting.
            var translatedIndex = TranslateSelectionIndex(selectedIndex);

            if (selectedClassProspectiveIndex == translatedIndex)
            {
                return;
            }

            selectedClassProspectiveIndex = translatedIndex;

            int classInfoIndex = GetClassInformationIndex();

            // If user clicks on the same item when it is expanded, then 'OnClassButtonCollapse'
            // is invoked to deselect the item. This causes 'OnClassViewSelectionChanged' to be
            // called again, with 'SelectedIndex' set to '-1', indicating that no item is selected,
            // in which case we need to hide the ClassInformationView.
            if (selectedClassProspectiveIndex == -1)
            {
                if (classInfoIndex != -1)
                {
                    (collection[classInfoIndex] as ClassInformationViewModel).ClassDetailsVisibility = false;
                    currentClass = null;
                }
                OrderListItems();
                return;
            }
            else
            {
                (collection[classInfoIndex] as ClassInformationViewModel).ClassDetailsVisibility = true;
            }

            currentClass = collection[selectedIndex] as NodeCategoryViewModel;
            OrderListItems(); // Selection change, we may need to reorder items.
        }
예제 #12
0
        public void FindInsertionPointByNameTest()
        {
            var elementVM = CreateCustomNodeViewModel("AMember", "TopCategory");

            viewModel.InsertEntry(elementVM, elementVM.Model.Categories);

            elementVM = CreateCustomNodeViewModel("ZMember", "TopCategory");
            viewModel.InsertEntry(elementVM, elementVM.Model.Categories);

            var listOfMembers = viewModel.BrowserRootCategories.First(c => c.Name == "TopCategory").Items;

            var index = NodeCategoryViewModel.FindInsertionPointByName(listOfMembers, "BMember");

            Assert.AreEqual(1, index);

            elementVM = CreateCustomNodeViewModel("BMember", "TopCategory");
            viewModel.InsertEntry(elementVM, elementVM.Model.Categories);

            index = NodeCategoryViewModel.FindInsertionPointByName(listOfMembers, "BMember");

            Assert.AreEqual(1, index);
        }
예제 #13
0
        private static IEnumerable <NodeCategoryViewModel> GetTreeBranchToNode(
            NodeCategoryViewModel rootNode, NodeSearchElement leafNode)
        {
            var  nodesOnBranch = new Stack <NodeCategoryViewModel>();
            var  nameStack     = new Stack <string>(leafNode.Categories.Reverse());
            var  target        = rootNode;
            bool isCheckedForClassesCategory = false;

            while (nameStack.Any())
            {
                var next       = nameStack.Pop();
                var categories = target.SubCategories;
                var newTarget  = categories.FirstOrDefault(c => c.Name == next);
                if (newTarget == null)
                {
                    // The last entry in categories list can be a class name. When the desired class
                    // cannot be located with "MyAssembly.MyNamespace.ClassCandidate" pattern, try
                    // searching with "MyAssembly.MyNamespace.Classes.ClassCandidate" instead. This
                    // is because a class always resides under a "ClassesNodeCategoryViewModel" node.
                    //
                    if (!isCheckedForClassesCategory && nameStack.Count == 0)
                    {
                        nameStack.Push(next);
                        nameStack.Push(Configurations.ClassesDefaultName);

                        isCheckedForClassesCategory = true;
                        continue;
                    }

                    return(Enumerable.Empty <NodeCategoryViewModel>());
                }
                nodesOnBranch.Push(target);
                target = newTarget;
            }

            nodesOnBranch.Push(target);
            return(nodesOnBranch);
        }
예제 #14
0
        public void ElementTypeToBoolConverterTest()
        {
            ElementTypeToBoolConverter converter = new ElementTypeToBoolConverter();
            var NseVM = new NodeSearchElementViewModel(
                new NodeModelSearchElement(new TypeLoadData(typeof(Dynamo.Nodes.Symbol))), null);
            var NcVM  = new NodeCategoryViewModel("");
            var RncVM = new RootNodeCategoryViewModel("");
            var CncVM = new ClassesNodeCategoryViewModel(RncVM);

            object result;

            //1. Element is null.
            //2. Element is NodeSearchElement.
            //3. Element is NodeCategoryViewModel.
            //4. Element is RootNodeCategoryViewModel.
            //5. Element is RootNodeCategoryViewModel with ClassesNodeCategoryViewModel.

            // 1 case
            result = converter.Convert(null, null, null, null);
            Assert.AreEqual(false, result);

            // 2 case
            result = converter.Convert(NseVM, null, null, null);
            Assert.AreEqual(false, result);

            // 3 case
            result = converter.Convert(NcVM, null, null, null);
            Assert.AreEqual(true, result);

            // 4 case
            result = converter.Convert(RncVM, null, null, null);
            Assert.AreEqual(true, result);

            // 5 case
            RncVM.SubCategories.Add(CncVM);
            result = converter.Convert(RncVM, null, null, null);
            Assert.AreEqual(false, result);
        }
예제 #15
0
 private static IEnumerable <NodeSearchElementViewModel> GetVisibleSearchResults(NodeCategoryViewModel category)
 {
     foreach (var item in category.Items)
     {
         var sub = item as NodeCategoryViewModel;
         if (sub != null)
         {
             foreach (var visible in GetVisibleSearchResults(sub))
             {
                 yield return(visible);
             }
         }
         else
         {
             yield return((NodeSearchElementViewModel)item);
         }
     }
 }
예제 #16
0
 internal SearchMemberGroup(string fullyQualifiedName, NodeCategoryViewModel category = null)
 {
     FullyQualifiedName = fullyQualifiedName;
     Category           = category;
     members            = new List <NodeSearchElementViewModel>();
 }
예제 #17
0
        private void InsertEntryIntoNewCategory(
            NodeCategoryViewModel category,
            NodeSearchElementViewModel entry,
            IEnumerable <string> categoryNames)
        {
            if (!categoryNames.Any())
            {
                AddEntryToExistingCategory(category, entry);
                return;
            }

            // With the example of 'MyAssembly.MyNamespace.MyClass.Foo', 'path' would have been
            // set to 'MyAssembly' here. The Select statement below would store two entries into
            // 'newTargets' variable:
            //
            //      NodeCategoryViewModel("MyAssembly.MyNamespace")
            //      NodeCategoryViewModel("MyAssembly.MyNamespace.MyClass")
            //
            var path       = category.FullCategoryName;
            var newTargets = categoryNames.Select(name =>
            {
                path = MakeFullyQualifiedName(path, name);

                var cat = new NodeCategoryViewModel(name);
                cat.FullCategoryName = path;
                cat.Assembly         = entry.Assembly;
                return(cat);
            }).ToList();

            // The last entry 'NodeCategoryViewModel' represents a class. For our example the
            // entries in 'newTargets' are:
            //
            //      NodeCategoryViewModel("MyAssembly.MyNamespace")
            //      NodeCategoryViewModel("MyAssembly.MyNamespace.MyClass")
            //
            // Since all class entries are contained under a 'ClassesNodeCategoryViewModel',
            // we need to create a new 'ClassesNodeCategoryViewModel' instance, and insert it
            // right before the class entry itself to get the following list:
            //
            //      NodeCategoryViewModel("MyAssembly.MyNamespace")
            //      ClassesNodeCategoryViewModel("Classes")
            //      NodeCategoryViewModel("MyAssembly.MyNamespace.MyClass")
            //
            int indexToInsertClass = newTargets.Count - 1;
            var classParent        = indexToInsertClass > 0 ? newTargets[indexToInsertClass - 1] : category;
            var newClass           = new ClassesNodeCategoryViewModel(classParent);

            newTargets.Insert(indexToInsertClass, newClass);

            // Here, all the entries in 'newTargets' are added under 'MyAssembly' recursively,
            // resulting in the following hierarchical structure:
            //
            //      NodeCategoryViewModel("MyAssembly")
            //          NodeCategoryViewModel("MyAssembly.MyNamespace")
            //              ClassesNodeCategoryViewModel("Classes")
            //                  NodeCategoryViewModel("MyAssembly.MyNamespace.MyClass")
            //
            foreach (var newTarget in newTargets)
            {
                category.SubCategories.Add(newTarget);
                category = newTarget;
            }

            AddEntryToExistingCategory(category, entry);
        }
예제 #18
0
        /// <summary>
        /// Insert a new search element under the category.
        /// </summary>
        /// <param name="entry">This could represent a function of a given
        /// class. For example, 'MyAssembly.MyNamespace.MyClass.Foo'.</param>
        /// <param name="categoryNames">A list of entries that make up the fully qualified
        /// class name that contains function 'Foo', e.g. 'MyAssembly.MyNamespace.MyClass'.
        /// </param>
        internal void InsertEntry(NodeSearchElementViewModel entry, IEnumerable <string> categoryNames)
        {
            var    nameStack = new Stack <string>(categoryNames.Reverse());
            var    target    = libraryRoot;
            string fullyQualifiedCategoryName        = "";
            ClassesNodeCategoryViewModel targetClass = null;

            while (nameStack.Any())
            {
                var next = nameStack.Pop();
                fullyQualifiedCategoryName = MakeFullyQualifiedName(fullyQualifiedCategoryName, next);

                var categories = target.SubCategories;
                NodeCategoryViewModel targetClassSuccessor = null;
                var newTarget = categories.FirstOrDefault(c =>
                {
                    // Each path has one class. We should find and save it.
                    if (c is ClassesNodeCategoryViewModel)
                    {
                        targetClass = c as ClassesNodeCategoryViewModel;
                        // As soon as ClassesNodeCategoryViewModel is found we should search
                        // through all it classes and save result.
                        targetClassSuccessor = c.SubCategories.FirstOrDefault(c2 => c2.Name == next);
                        return(targetClassSuccessor != null);
                    }

                    return(c.Name == next);
                });
                if (newTarget == null)
                {
                    // For the first iteration, this would be 'MyAssembly', and the second iteration 'MyNamespace'.
                    var targetIsRoot = target == libraryRoot;
                    newTarget = targetIsRoot ? new RootNodeCategoryViewModel(next) : new NodeCategoryViewModel(next);
                    newTarget.FullCategoryName = fullyQualifiedCategoryName;
                    newTarget.Assembly         = entry.Assembly;
                    // Situation when we to add only one new category and item as it child.
                    // New category should be added to existing ClassesNodeCategoryViewModel.
                    // Make notice: ClassesNodeCategoryViewModel is always first item in
                    // all subcategories.
                    if (nameStack.Count == 0 && !target.IsClassButton &&
                        target.SubCategories[0] is ClassesNodeCategoryViewModel)
                    {
                        target.SubCategories[0].SubCategories.Add(newTarget);
                        AddEntryToExistingCategory(newTarget, entry);
                        return;
                    }

                    // We are here when target is the class. New category should be added
                    // as child of it. So class will turn into usual category.
                    // Here we are take class, remove it from ClassesNodeCategoryViewModel
                    // and attach to it parrent.
                    if (targetClass != null)
                    {
                        if (targetClass.SubCategories.Remove(target))
                        {
                            targetClass.Parent.SubCategories.Add(target);
                        }
                        // Delete empty classes container.
                        if (targetClass.IsClassButton)
                        {
                            targetClass.Parent.SubCategories.RemoveAt(0);
                        }

                        targetClass.Dispose();
                    }

                    // Situation when we need to add only one new category and item.
                    // Before adding of it we need create new ClassesNodeCategoryViewModel
                    // as soon as new category will be a class.
                    if (nameStack.Count == 0 && !targetIsRoot)
                    {
                        targetClass = new ClassesNodeCategoryViewModel(target);

                        target.SubCategories.Insert(0, targetClass);
                        target.SubCategories[0].SubCategories.Add(newTarget);
                        AddEntryToExistingCategory(newTarget, entry);
                        return;
                    }

                    target.InsertSubCategory(newTarget);

                    // Proceed to insert the new entry under 'newTarget' category with the remaining
                    // name stack. In the first iteration this would have been 'MyNamespace.MyClass'.
                    InsertEntryIntoNewCategory(newTarget, entry, nameStack);
                    return;
                }
                // If we meet ClassesNodecategoryViewModel during the search of newTarget,
                // next newTarget is specified in targetClassSuccessor.
                if (targetClassSuccessor != null)
                {
                    target = targetClassSuccessor;
                }
                else
                {
                    target = newTarget;
                }
            }
            AddEntryToExistingCategory(target, entry);
        }
예제 #19
0
        private bool ExpandCategory(IEnumerable <NodeCategoryViewModel> categories, NodeCategoryViewModel selectedClass)
        {
            bool foundSelectedClass = false;

            // Get all current expanded categories.
            var allExpandedCategories = categories.Where(cat =>
            {
                return(cat.IsExpanded && (!(cat is ClassesNodeCategoryViewModel)));
            }).ToList();
            var categoryToBeExpanded = categories.FirstOrDefault(cat => cat == selectedClass);

            // If categoryToBeExpanded is null, that means the clicked item does not
            // represent a category button, but a class button. In the recursive call
            // the category in which this clicked class belong will be identified.
            if (categoryToBeExpanded != null)
            {
                categoryToBeExpanded.IsExpanded = !categoryToBeExpanded.IsExpanded;
                foundSelectedClass = true;
            }

            // Get expanded categories that should be collapsed.
            allExpandedCategories.Remove(categoryToBeExpanded);

            // Close all expanded categories except the one that contains the target
            // class button. If the clicked NodeCategoryViewModel represents a category
            // itself, then expand it and close out other sibling NodeCategoryViewModel.
            foreach (var expandedCategory in allExpandedCategories)
            {
                var searchFurtherInNextLevel = true;

                // If class button was clicked.
                if (selectedClass.IsClassButton)
                {
                    var categoryClasses = expandedCategory.Items[0] as ClassesNodeCategoryViewModel;
                    if (categoryClasses != null) // There are classes under this category...
                    {
                        if (expandedCategory.IsClassButton)
                        {
                            // If the category does not contain any sub category,
                            // then we won't look for the selected class within it.
                            expandedCategory.IsExpanded = false;
                            searchFurtherInNextLevel    = false;
                        }
                        else if (categoryClasses.Items.Contains(selectedClass))
                        {
                            // If the category contains the selected class directly
                            // within, then keep it expanded instead of collapsing it.
                            expandedCategory.IsExpanded = true;

                            // Found the selected class! Collapse all other sub categories.
                            foreach (var ele in expandedCategory.SubCategories)
                            {
                                ele.IsExpanded = false;
                            }

                            searchFurtherInNextLevel = false;
                        }
                    }
                }

                if (searchFurtherInNextLevel)
                {
                    var childCategories = expandedCategory.Items.OfType <NodeCategoryViewModel>();
                    expandedCategory.IsExpanded = ExpandCategory(childCategories, selectedClass);
                }

                // If the category remains expanded after this, we can
                // be sure that the selected class was found within it.
                foundSelectedClass = foundSelectedClass || expandedCategory.IsExpanded;
            }

            return(foundSelectedClass);
        }
예제 #20
0
 private void AddEntryToExistingCategory(NodeCategoryViewModel category,
                                         NodeSearchElementViewModel entry)
 {
     category.RequestBitmapSource += SearchViewModelRequestBitmapSource;
     category.Entries.Add(entry);
 }
예제 #21
0
        /// <summary>
        ///     Performs a search and updates the observable SearchResults property.
        /// </summary>
        /// <param name="query"> The search query </param>
        public void SearchAndUpdateResults(string query)
        {
            if (Visible != true)
            {
                return;
            }

            // deselect the last selected item
            if (visibleSearchResults.Count > SelectedIndex)
            {
                visibleSearchResults[SelectedIndex].IsSelected = false;
            }

            // if the search query is empty, go back to the default treeview
            if (string.IsNullOrEmpty(query))
            {
                return;
            }

            // clear visible results list
            visibleSearchResults.Clear();

            foreach (var category in SearchRootCategories)
            {
                category.DisposeTree();
            }

            SearchRootCategories.Clear();

            if (string.IsNullOrEmpty(query))
            {
                return;
            }

            var result =
                Model.Search(query).Where(r => r.IsVisibleInSearch).Take(MaxNumSearchResults).ToList();

            // Add top result
            var firstRes = result.FirstOrDefault();

            if (firstRes == null)
            {
                return; //No results
            }
            var topResultCategory = new RootNodeCategoryViewModel("Top Result");

            SearchRootCategories.Add(topResultCategory);

            var copy    = MakeNodeSearchElementVM(firstRes);
            var catName = MakeShortCategoryString(firstRes.FullCategoryName);

            var breadCrumb = new NodeCategoryViewModel(catName)
            {
                IsExpanded = true
            };

            breadCrumb.Entries.Add(copy);
            topResultCategory.SubCategories.Add(breadCrumb);
            topResultCategory.Visibility = true;
            topResultCategory.IsExpanded = true;

            SearchRootCategories.AddRange(CategorizeEntries(result, true));

            visibleSearchResults.AddRange(SearchRootCategories.SelectMany(GetVisibleSearchResults));

            if (visibleSearchResults.Any())
            {
                SelectedIndex = 0;
                visibleSearchResults[0].IsSelected = true;
            }

            SearchResults.Clear();
            foreach (var x in visibleSearchResults)
            {
                SearchResults.Add(x);
            }
        }