patterncsharpMinor
Code Explorer View Models
Viewed 0 times
codeexplorerviewmodels
Problem
Continuing the series of Code Explorer posts, here is the collection of view models for the tree nodes:
This is the interface for nodes with a declaration.
And here is the abstract view model they are all based on:
```
public abstract class CodeExplorerItemViewModel : ViewModelBase
{
private List _items = new List();
public List Items
{
get { return _items; }
protected set
{
_items = value;
OnPropertyChanged();
}
}
public bool IsExpanded { get; set; }
public abstract string Name { get; }
public abstract string NameWithSignature { get; }
public abstract BitmapImage CollapsedIcon { get; }
public abstract BitmapImage ExpandedIcon { get; }
public abstract CodeExplorerItemViewModel Parent { get; }
public abstract QualifiedSelection? QualifiedSelection { get; }
public CodeExplorerItemViewModel GetChild(string name)
{
foreach (var item in _items)
{
if (item.Name == name)
{
return item;
}
var result = item.GetChild(name);
if (result != null)
{
return result;
}
}
return null;
}
public Declaration GetSelectedDeclaration()
{
return this is ICodeExplorerDeclarationViewModel
? ((ICodeExplorerDeclarationViewModel)this).Declaration
: null;
}
public void AddChild(CodeExplorerItemViewModel item)
{
_items.Add(item);
}
public void ReorderItems(bool sortByName, bool sortByType)
{
if (sortByType)
{
Items = sortByName
? Items.OrderBy(o => o, new CompareByType()).ThenBy(t => t, new CompareByName()).ToList()
: Items.OrderBy(o => o, new CompareByType()).ThenBy(t => t, new CompareBySelection()).To
This is the interface for nodes with a declaration.
public interface ICodeExplorerDeclarationViewModel
{
Declaration Declaration { get; }
}And here is the abstract view model they are all based on:
```
public abstract class CodeExplorerItemViewModel : ViewModelBase
{
private List _items = new List();
public List Items
{
get { return _items; }
protected set
{
_items = value;
OnPropertyChanged();
}
}
public bool IsExpanded { get; set; }
public abstract string Name { get; }
public abstract string NameWithSignature { get; }
public abstract BitmapImage CollapsedIcon { get; }
public abstract BitmapImage ExpandedIcon { get; }
public abstract CodeExplorerItemViewModel Parent { get; }
public abstract QualifiedSelection? QualifiedSelection { get; }
public CodeExplorerItemViewModel GetChild(string name)
{
foreach (var item in _items)
{
if (item.Name == name)
{
return item;
}
var result = item.GetChild(name);
if (result != null)
{
return result;
}
}
return null;
}
public Declaration GetSelectedDeclaration()
{
return this is ICodeExplorerDeclarationViewModel
? ((ICodeExplorerDeclarationViewModel)this).Declaration
: null;
}
public void AddChild(CodeExplorerItemViewModel item)
{
_items.Add(item);
}
public void ReorderItems(bool sortByName, bool sortByType)
{
if (sortByType)
{
Items = sortByName
? Items.OrderBy(o => o, new CompareByType()).ThenBy(t => t, new CompareByName()).ToList()
: Items.OrderBy(o => o, new CompareByType()).ThenBy(t => t, new CompareBySelection()).To
Solution
GetSelectedDeclaration is ugly and a little bit uncomprehensive. CodeExplorerItemViewModel does not implement ICodeExplorerDeclarationViewModel, so this method can only return something on a subclassof it like
CodeExplorerProjectViewModel. I would prefer to have a virtual method and override it. //on `CodeExplorerItemViewModel`
public virtual Declaration GetSelectedDeclaration()
{
return null;
}
//on `CodeExplorerProjectViewModel `
public override Declaration GetSelectedDeclaration()
{
return Declaration;
}ReorderItems is ok but there's room for improvement.What you know is that the
OrderBy may be performed by any comparer and it may be needed a ThenBy if sortByType is selected.You also always need one instance of
CompareByName or CompareBySelection. I sugest an implementation where you start by instatiating the right comparer:
public void ReorderItems(bool sortByName, bool sortByType)
{
var comparer = sortByName ? new CompareByName() : new CompareBySelection();
if(sortByType){
Items = Items
.OrderBy(o => o, new CompareByType())
.ThenBy(comparer)
.ToList();
}else{
Items = Items
.OrderBy(o => o, comparer))
.ToList();
}
}Your
AddNodesToTree could use a variable to store the nodes before adding them to folder.var nodes = items.Where(item => parents.Contains(item) ||
parents.Any(parent =>
(item.ParentDeclaration != null && item.ParentDeclaration.Equals(parent)) ||
item.ComponentName == parent.ComponentName)
).ToList()
folder.AddNodes(nodes);CodeExplorerItemViewModel could have a Root property that would return the first node, sou you wouldn't have to write the while on CodeExplorerComponentViewModel-Code Snippets
//on `CodeExplorerItemViewModel`
public virtual Declaration GetSelectedDeclaration()
{
return null;
}
//on `CodeExplorerProjectViewModel `
public override Declaration GetSelectedDeclaration()
{
return Declaration;
}public void ReorderItems(bool sortByName, bool sortByType)
{
var comparer = sortByName ? new CompareByName() : new CompareBySelection();
if(sortByType){
Items = Items
.OrderBy(o => o, new CompareByType())
.ThenBy(comparer)
.ToList();
}else{
Items = Items
.OrderBy(o => o, comparer))
.ToList();
}
}var nodes = items.Where(item => parents.Contains(item) ||
parents.Any(parent =>
(item.ParentDeclaration != null && item.ParentDeclaration.Equals(parent)) ||
item.ComponentName == parent.ComponentName)
).ToList()
folder.AddNodes(nodes);Context
StackExchange Code Review Q#129507, answer score: 3
Revisions (0)
No revisions yet.