/// <summary> /// The TREELIB (see FilterTreeViewLib (Project) > Properties > Conditional Compilation Symbol) /// switch determines whether the TreeLib LevelOrder traversal function is used or not. /// The point for training is here: /// /// Both functions are equivalent but using the TreeLib traversal function should simplify /// the problem of efficiently traversing any tree in the given order. /// </summary> #if TREELIB ///<summary> /// Convert a Model into a ViewModel using /// a LevelOrderTraversal Algorithm via TreeLib library. ///</summary> internal static MetaLocationViewModel GetViewModelFromModel(MetaLocationModel srcRoot) { if (srcRoot == null) { return(null); } var srcItems = TreeLib.BreadthFirst.Traverse.LevelOrder(srcRoot, i => i.Children); var dstIdItems = new Dictionary <int, MetaLocationViewModel>(); MetaLocationViewModel dstRoot = null; foreach (var node in srcItems.Select(i => i.Node)) { if (node.Parent == null) { dstRoot = new MetaLocationViewModel(node, null); dstIdItems.Add(dstRoot.ID, dstRoot); } else { MetaLocationViewModel vmParentItem; // Find parent ViewModel for Model dstIdItems.TryGetValue(node.Parent.ID, out vmParentItem); var dstNode = new MetaLocationViewModel(node, vmParentItem); vmParentItem.ChildrenAdd(dstNode); // Insert converted ViewModel below ViewModel parent dstIdItems.Add(dstNode.ID, dstNode); } } dstIdItems.Clear(); // Destroy temp ID look-up structure return(dstRoot); }
/// <summary> /// Add a child item including a reference to a backupnode /// (add to backupnode is determined by <paramref name="bAddBackup"/>). /// </summary> /// <param name="child"></param> /// <param name="bAddBackup"></param> private void ChildrenAdd(MetaLocationViewModel child, bool bAddBackup = true) { try { if (HasDummyChild == true) { lock (_itemsLock) { _Children.Clear(); } } lock (_itemsLock) { _Children.Add(child); } if (bAddBackup == true) { _BackUpNodes.Add(child); } } catch { } }
private void ChildrenRemove(MetaLocationViewModel child, bool bRemoveBackup = true) { Application.Current.Dispatcher.Invoke(() => { _Children.Remove(child); }, _ChildrenEditPrio); if (bRemoveBackup == true) { _BackUpNodes.Remove(child); } }
/// <summary> /// Add a rootitem into the root items collection - /// always adds into the backup root items collection and /// only adds into the observable collection /// if <paramref name="addBackupItemOnly"/> is false. /// </summary> /// <param name="vmItem"></param> /// <param name="addBackupItemOnly"></param> protected void RootsAdd(MetaLocationViewModel vmItem , bool addBackupItemOnly) { _BackUpCountryRoots.Add(vmItem); if (addBackupItemOnly == false) { _CountryRootItems.Add(vmItem); } }
private void ChildrenRemove(MetaLocationViewModel child, bool bRemoveBackup = true) { lock (_itemsLock) { _Children.Remove(child); } if (bRemoveBackup == true) { _BackUpNodes.Remove(child); } }
/// <summary> /// Add a child item including a reference to a backupnode /// (add to backupnode is determined by <paramref name="bAddBackup"/>). /// </summary> /// <param name="child"></param> /// <param name="bAddBackup"></param> private void ChildrenAdd(MetaLocationViewModel child, bool bAddBackup = true) { if (HasDummyChild == true) { Application.Current.Dispatcher.Invoke(() => { _Children.Clear(); }, _ChildrenEditPrio); } Application.Current.Dispatcher.Invoke(() => { _Children.Add(child); }, _ChildrenEditPrio); if (bAddBackup == true) { _BackUpNodes.Add(child); } }
/// <summary> /// Implement a PostOrder matching algorithm with one root node /// and returns the number of matching children found. /// </summary> /// <param name="root"></param> /// <param name="filterString"></param> /// <returns></returns> private int MatchNodes( MetaLocationViewModel root , SearchParams searchParams) { var toVisit = new Stack <MetaLocationViewModel>(); var visitedAncestors = new Stack <MetaLocationViewModel>(); int MatchCount = 0; toVisit.Push(root); while (toVisit.Count > 0) { var node = toVisit.Peek(); if (node.ChildrenCount > 0) { if (PeekOrDefault(visitedAncestors) != node) { visitedAncestors.Push(node); PushReverse(toVisit, node.BackUpNodes); continue; } visitedAncestors.Pop(); } // Process Node and count matches (if any) int matchStart = -1; MatchType match = MatchType.NoMatch; match = node.ProcessNodeMatch(searchParams, out matchStart); node.SetMatch(match, matchStart, matchStart + searchParams.SearchString.Length); if (node.Match == MatchType.NodeMatch) { MatchCount++; } if (node.Match == MatchType.SubNodeMatch || node.Match == MatchType.Node_AND_SubNodeMatch) { node.SetExpand(true); } else { node.SetExpand(false); } toVisit.Pop(); } return(MatchCount); }
/// <summary> /// Parameterized Class Constructor /// </summary> public MetaLocationViewModel( BusinessLib.Models.MetaLocationModel locationModel , MetaLocationViewModel parent ) : this() { Parent = parent; _LocalName = locationModel.LocalName; ID = locationModel.ID; Latitude = locationModel.Geo_lat; Longitude = locationModel.Geo_lng; TypeOfLocation = locationModel.Type; ChildrenClear(false); // Lazy Load Children !!! }
/// <summary> /// Returns the string path either: /// 1) for the <paramref name="current"/> item or /// 2) for this item (if optional parameter <paramref name="current"/> is not set). /// </summary> /// <param name="current"></param> /// <returns></returns> public string GetStackPath(MetaLocationViewModel current = null) { if (current == null) { current = this; } string result = string.Empty; // Traverse the list of parents backwards and // add each child to the path while (current != null) { result = "/" + LocalName + result; current = current.Parent; } return(result); }
/// <summary> /// /// </summary> /// <param name="zipContainerFile"></param> /// <param name="countryXMLFile"></param> /// <param name="regionsXMLFile"></param> /// <param name="citiesXMLFile"></param> public async Task LoadData( string zipContainerFile , string countryXMLFile , string regionsXMLFile , string citiesXMLFile) { var isoCountries = await BusinessLib.Database.LoadData(zipContainerFile , countryXMLFile , regionsXMLFile , citiesXMLFile); foreach (var item in isoCountries) { Application.Current.Dispatcher.Invoke(() => { var vmItem = MetaLocationViewModel.GetViewModelFromModel(item); RootsAdd(vmItem, true); //Root.RootsAdd(vmItem, false); // Make all items initially visible }, DispatcherPriority.ApplicationIdle); } }
/// <summary> /// /// </summary> /// <param name="zipContainerFile"></param> /// <param name="countryXMLFile"></param> /// <param name="regionsXMLFile"></param> /// <param name="citiesXMLFile"></param> public async Task LoadData( string zipContainerFile , string countryXMLFile , string regionsXMLFile , string citiesXMLFile) { var isoCountries = await BusinessLib.Database.LoadData(zipContainerFile , countryXMLFile , regionsXMLFile , citiesXMLFile); foreach (var item in isoCountries) { lock (_itemsLock) { var vmItem = MetaLocationViewModel.GetViewModelFromModel(item); RootsAdd(vmItem, true); //Root.RootsAdd(vmItem, false); // Make all items initially visible } } }
/// <summary> /// Convert a Model into a ViewModel using /// a LevelOrderTraversal Algorithm /// </summary> /// <param name="srcRoot"></param> internal static MetaLocationViewModel GetViewModelFromModel(MetaLocationModel srcRoot) { if (srcRoot == null) { return(null); } MetaLocationViewModel dstRoot = new MetaLocationViewModel(srcRoot, null); Queue <MetaLocationModel> srcQueue = new Queue <MetaLocationModel>(); Queue <MetaLocationViewModel> dstQueue = new Queue <MetaLocationViewModel>(); srcQueue.Enqueue(srcRoot); dstQueue.Enqueue(dstRoot); while (srcQueue.Count() > 0) { MetaLocationModel srcCurrent = srcQueue.Dequeue(); MetaLocationViewModel dstCurrent = dstQueue.Dequeue(); ////Console.WriteLine(string.Format("{0,4} - {1}" //// , iLevel, current.GetPath())); foreach (var item in srcCurrent.Children) { var dstVM = new MetaLocationViewModel(item, dstCurrent); dstCurrent.ChildrenAddBackupNodes(dstVM); srcQueue.Enqueue(item); dstQueue.Enqueue(dstVM); } } return(dstRoot); }
/// <summary> /// Implement a PostOrder matching algorithm with one root node /// and returns the number of matching children found. /// </summary> /// <param name="root"></param> /// <param name="filterString"></param> /// <returns></returns> private Task <int> MatchNodesAsync( MetaLocationViewModel root , SearchParams searchParams) { return(Task.Run <int>(() => { return MatchNodes(root, searchParams); })); }
/// <summary> /// Add a child node to a backupnode only. /// </summary> /// <param name="child"></param> private void ChildrenAddBackupNodes(MetaLocationViewModel child) { _BackUpNodes.Add(child); }