Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement hierarchical data browsing #3

Open
stuarta0 opened this issue May 13, 2015 · 2 comments
Open

Implement hierarchical data browsing #3

stuarta0 opened this issue May 13, 2015 · 2 comments

Comments

@stuarta0
Copy link
Owner

In the previous version of the library (in SVN, not git; not included in commit history), the tree layout was defined by an XML template, with a callback for formatting when the threaded operation for loading child nodes had completed.

Problems with the old method:

  • Most of the logic was hard coded into a UserControl with a private TreeView so you couldn't do anything with the actual tree control. This is pretty much the issue - you have no control.
  • Attempting to handle node Font from the formatting callback caused OutOfMemoryException for large data due to GDI objects exceeding 10,000 (a fault of the WinForms TreeView in fact).
  • Efficiency issues relating to the way queries were constructed and executed. This has been resolved with the current library.

Aims:

  • Still provide the killer feature of having a fully searchable tree based on any field anywhere in the data that is very responsive (whether this is threaded or not).
  • Disconnect the UI from the definition and fetching of the tree (obviously). This will allow using other UI toolkits with the hierarchical data without code duplication.
  • Provide modular code to swap in a different fetch strategy so the UI is oblivious to whether the data has come from a database via the standard dbqf functionality or whether the strategy is just supplying nodes itself (e.g. some nodes may not be backed by data like a root node labelled 'Invoices').
  • Add DTO for serialisation of tree definition if plausible to do so (it'll probably needs it's own basic fetch strategy to accompany it)
  • Nice to have: provide a user-editable tree configurator.
@stuarta0
Copy link
Owner Author

From written notes (2014):

To abstract the UI, we need to represent our own tree structure & have an adapter at the end which converts into the concrete UI implementation.

So we use the current query builder class. It gets us the data we want in a data table. We sort this data by each sort field in order. Then we group the data : first group followed by second group hierarchicaly below, followed by third etc. In the end we have a tree structure (either 1 deep i.e. a list, or N deep) that we give to the tree.

TreeControl will perform actions such as expand/collapse node and select node. Do we care? Maybe we only care about GetChildren(node). Back up, what about the whole "can I expand or not?" i.e. has children logic? OK so we have our base adapter<T> where T is the tree node type. We have our WinForms implementation which is adapter<TreeNode>. If we provide an Expand(T) we can do our query logic here as well as load in advance (and we can decide if we want to add children to detect load on demand or whether we've already supplied the data).

Let's think overall - we want to swap our UI implementation with a minimum of effort. Therefore we want to be determining our nodes hierarchy & then hand this off to a class to create the UI nodes - like how the PresetAdapter calls its abstract method to create its concrete PresetPart<T>. The difference here is that we need to know what nodes hierarchy to make & that requires querying the database. Since we abstract the database implementation this would probably fall to the inherited class to determine. But then we're miing concerns of getting data with displaying data...

How do we handle custom behaviours? e.g. if we wanted our implementation to handle determining whether a node has children when it hasn't been loaded yet? This kind of behaviour is not related to the UI, so is it the application that provides the implementation of this & couples it with the existing UI code? Yes. So if the concrete implementation of TreeNode creation inherits, then we need to supply this behaviour to the adapter, not inherit. So this is where the adapter needs to ask something for the nodes. We could supply a default implementation (or two) that does the "get node data up until next dynamic node" or the "get nodes & their immediate children so we know if we can expand" logic. So this probably means separating the whole node creation sub-tree logic into this class - which actually means the whole "group by" logic can be swapped out too.

1432072865600-612282390

The adapter will need to notify on nodes added/removed and also expanded/contracted so the UI can update accordingly. Also the UI TreeNodes need to be notified of changes somehow. Not just text but colours/styles or whatever the concrete node creation provides. This will allow us to update nodes (& their hierarchies) if live changes occur in our application. For example the state of an object changes to 'complete' from 'pending' & its colour changes from orange to green or it relocates the node to another subtree. If it relocates to another tree it implies the node provider will have knowledge of the existing tree structure implying that the relationship is actually from the provider to the adapter; i.e. the adapter fires an event to get nodes & the provider responds. Actually this is OK because the adapter will have events for expand/contract/add/delete s othe provider can respond to expand & calculate the child nodes to then add as necessary, then the flow would be:

  • UI node expanded (without expanding)
  • Adapter expanded
  • NodeProvider handles, add child nodes
  • Adapter nodes added
  • UI add nodes
  • UI actually expand node

@stuarta0
Copy link
Owner Author

To save dumping my current brain, here's a similar thought process:
http://www.codeproject.com/Articles/26288/Simplifying-the-WPF-TreeView-by-Using-the-ViewMode

In a nutshell, provide a viewmodel/adapter Node object with all hierarchy bundled into it and mimic the object in the UI. This works in WPF as per the article above and would be possible to make it work (a little more manually as per previous comment) in WinForms. See 1b70963 for the basis of this behaviour.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant