How to implement a dependency tree of updating objects? - c#

Edit: I am not looking for an implementation but just for some keywords to search and methodologies to get me started.
I am struggling with generating a dependency tree where child nodes are updated by an external process and the requirement is to update all parent nodes of updated child nodes.
Example: Imagine a tree such as this: O [parent], O(l) [left child], O(r) [right child], O(ll), O(lr), O(rl), and O(rr). O(ll), O(lr), O(rl), and O(rr) have reference to a data collection that is updated at random intervals).
I want to implement a pull process, where at certain intervals a process checks whether O is updated. "Updated" is defined as being updated when all child nodes are updated, else just the cached value(result) of that node is used. The pull process's job is to ensure that O is updated when any of the child nodes is not updated. This means that the process needs to traverse the tree and check whether O(ll), O(lr), O(rl), and O(rr) are updated. If the data collection, those child nodes reference, are updated since the last update of those child nodes then those child nodes need to be updated as function of the changed data collection. If the data collection is updated and hence the child nodes O(ll), O(lr), O(rl), and O(rr) are updated as well and this means that O(l) and O(r) also need to be updated and subsequently O will also be updated. Each child node is input to its parent node.
The complexity here is that each child node is shared among different trees, meaning, a child node of one tree can also be any child node of another tree. The purpose of this structure is to avoid the re-calculation of a child node when it is already up-to-date. The child nodes are shared if different trees implement a child node with the exact same functionality (function and parameterization) as the already existing child node.
I am stuck with the design of this structure and how to go about implementing it. I have not provided code yet because I am stuck with the design thought process. Essentially each child is function and depends on dependent functions itself.
What makes me wonder is whether C# offers the ability to decorate methods and classes in order to simplify the checking of whether a node is updated or not. Also does lazy evaluation play a role in this process at all?

I suggest defining a class that keeps track whether its children have been updated via a flag, e.g. a Boolean named Dirty. A node in the tree can tell its parents to become dirty by raising an event. When a node returns its own value, it should check the flag and recompute its own value only when needed. When recomputing, it should check the Value of each child, each of which will then check its own dirty flag, and so on, recursively.
class Node<T>
{
event EventHandler Changed;
private T _value;
private bool _dirty = true;
private List<Node<T>> _children = new List<Node<T>>();
public void AddChild(Node<T> child)
{
child.Changed += (s,e) => _dirty = true;
_children.Add(child);
}
protected void OnChanged()
{
if (Changed != null) Changed(this, new EventArgs());
}
public T Value
{
get
{
if (_dirty)
{
this.Value = ComputeValueFromChildren();
_dirty = false;
}
return _value;
}
set
{
_value = value;
OnChanged();
}
}
private T ComputeValueFromChildren()
{
var values = _children.Select( child => child.Value );
//Return the new value based on the children
}
}

Related

How we can just call the child element f scxml not (child of child)?

I am making a parser for state chart XML using C#. As we know there may be 2 children of state chart XML state and parallel so I make 2 functions one for state and other for parallel. How just I can call children of scxml not child of its child in my code it is calling all child+grandchild+grand_grand and so on.so Please some one explain how to just call child of scxml
I have tried to call its child but all its child comming
public static void Main(string[] args)
{
var
xdocXDocument.Load(#"C:/Users/path.xml");
IEnumerable<XElement> de = from el in xdoc.Descendants() select el;
foreach (XElement el in de)
{
if (string.Equals(el.Name.ToString(), "state", StringComparison.InvariantCultureIgnoreCase))
{
stat(el);
}
else if (string.Equals(el.Name.ToString(), "parallel", StringComparison.InvariantCultureIgnoreCase))
{
parr(el);
}
}
}
Error is that in my xml one child of xml is state and state child is parallel so its also calling child of child.
xml code is
I think you want to call .Nodes, rather than .Descendants, to get the child nodes, rather than all descendant nodes (eg grandchildren, etc). You can find documentation on this here: https://learn.microsoft.com/en-us/dotnet/api/system.xml.linq.xcontainer.nodes?view=netframework-4.8#System_Xml_Linq_XContainer_Nodes

why in treeView1 when i make CollapseAll and Expand it's not really doing it ?

When i'm running the program i see the root node
Countries
Then when i click on it i see all the countries nodes under Countries
But i want when running the program that it already will show all the countries nodes without clicking on Countries.
I tried in the constructor:
PopulateTree(mainPath, treeView1.Nodes.Add("Countries"));
treeView1.CollapseAll();
treeView1.Nodes[0].Expand();
The populatetree
public void PopulateTree(string dir, TreeNode node)
{
DirectoryInfo directory = new DirectoryInfo(dir);
foreach (DirectoryInfo d in directory.GetDirectories())
{
TreeNode t = new TreeNode(d.Name);
PopulateTree(d.FullName, t);
node.Nodes.Add(t);
}
foreach (FileInfo f in directory.GetFiles())
{
TreeNode t = new TreeNode(f.Name);
node.Nodes.Add(t);
}
}
But it's not doing it i still see Countries when running the program and to see all the childs nodes i need to click on Countries.
This lines not effect
treeView1.CollapseAll();
treeView1.Nodes[0].Expand();
TreeNode.Expand expands only Nodes[0] down to the next level of nodes. You should use TreeNode.ExpandAll to expand all child nodes of Countries node:
treeView1.Nodes[0].ExpandAll()
NOTE: There is one thing you should keep in mind. If handle is not created for TreeView control, then something like lazy collapsing-expanding is working here. I.e. each node has expandOnRealization and collapseOnRealization fields. When you are trying to expand node before tree handle is created, then just expandOnRealization flag is set to true. No TVM_EXPAND windows messages are sent to actually expand that node. Same for collapsing. When tree node is realized, then there is following code executed:
// If node expansion was requested before the handle was created,
// we can expand it now.
if (expandOnRealization) {
Expand();
}
// If node collapse was requested before the handle was created,
// we can expand it now.
if (collapseOnRealization) {
Collapse();
}
So, if node was marked both for collapsing and expanding, then it would be expanded first and then collapsed. I believe it's your case.

Searching a Child Control

I am using coded ui test with my windows store app.
My control hierarchy is :
UIPearsonPOCCommonViewFlipViewItem (XAMLFlipViewItem - > UIWebViewPane (XAMLWebViewPane) - > Rest of the content.
For rest of the child controls, there is no specific automation id or unique names and they look like html control for e.g. refer the image appended.
I want to iterate over the children of UIWebViewPane and reach to child DIV which is having the innerText.
I am relatively very new to coded ui test. I am unable to iterate over the children of UIWebViewPane(XAMLWebViewPane)
If the child control's inner text is unique, you could always search on that using the parent control in the definition. Ex:
public HtmlControl child()
{
HtmlControl parent = new HtmlControl(browser);
parent.SearchProperties["id"] = "[my id]";
HtmlControl child = new HtmlControl(parent);
child.SearchProperties["innerText"] = "[the inner text]";
return child;
}
If you truly want to iterate through, then you'll have to crawl the structure using the .GetParent() and .GetChildren() methods of the UITestControl class.
public HtmlControl child()
{
//First, we create an empty HtmlControl to return.
HtmlControl result = new HtmlControl()
//Specify the parent and get a collection of the children (this only goes one level,
// so if you have to go deeper, you'll have to nest your foreach loops and get
// children of the children, etc.
HtmlControl parent = new HtmlControl(browser);
parent.SearchProperties["id"] = "[my id]";
UITestControlCollection children = parent.GetChildren();
foreach (UITestControl child in children)
{
// If the child has the text you're looking for, then assign it to the result
// object and break the loop.
if (child.GetProperty("InnerText").ToString().Equals(searchTerm))
{
result = (HtmlControl)child;
break;
}
}
return result;
}
Personally, I'd try the first option. Your best bet, though, is to ask (politely) for the developer to add some unique and static tags to the HTML.

.NET TreeView: Attach objects to TreeNodes

In a .NET treeview you can create nodes, subnodes and elements.
All I seem to be able to do is give them names.
But how can I attach information (any object) to an element?
Use the Tag property of the TreeNode to attach an arbitrary object to it.
This doesn't affect the TreeView in any way. It is especially useful in your event handlers, (e.g. AfterSelect) because allows you to refer back to one of "your" objects from the TreeNode that is referenced.
Remember that Tag is of type Object, so you'll want to be careful how you access it. Here's some sample code to show how (I feel) it is best used:
public Form1()
{
InitializeComponent();
theTree.AfterSelect += (sender, args) => ShowSelectedNode();
}
private void ShowSelectedNode() {
var node = theTree.SelectedNode;
var viewable = node.Tag as IViewable;
if (viewable != null) {
viewable.View(this);
}
}
Note that this is the correct use of the as operator.

How do you get CSLA 3.02 BusinessListBase ListChanged event to identify the child object whose OnPropertyChanged triggered the event?

I have a project that is using CSLA 3.0.2.
I have a BusinessListBase collection object that has child items that have an IsDefault property.
When a child object has its IsDefault property set to true, I want to set the other child members IsDefault property to false.
I am calling the OnPropertyChanged("IsDefault") in the child setter and I have that raising the collections ListChanged event. However, the sender of the event is the Collection object, not the child object that raised the event. Nor is the child item in the ListChangedEventArgs (e).
How do I get a reference to the specific child instance that raised the event?
Or should I be doing this some other way? Like getting a reference to the parent in the child setter and doing it there?
Any help is appreciated.
I started with CSLA at 3.6, but I think this will work in CSLA 3:
You should find there is an OnChildChanged method you can override in your BusinessListBase collection class. That method has a parameter of Csla.Core.ChildChangedEventArgs which contains a reference to the child object that changed, and which property of the object it was that changed.
You can then loop the other children in the collection in that method to set them to IsDefault = false.
protected override void OnChildChanged(Csla.Core.ChildChangedEventArgs e)
{
base.OnChildChanged(e);
switch (e.PropertyChangedArgs.PropertyName)
{
case "IsDefault":
if ( ((ChildObjectType)e.ChildObject).IsDefault == true )
{
// then loop all the other childern
foreach (ChildObjectType child in this)
{
if (child != e.ChildObject && child.IsDefault == true)
{
child.IsDefault = false;
}
}
}
break;
}
}
If that doesn't work then the other approach is to use the Parent property in the child to get a reference to the collection and then call a method you have written in the BLB collection that updates the other children. You may need to look at the Parent's Parent depending on how your classes are set up.

Categories