Click here to Skip to main content
15,885,278 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I'm trying to create a extended treeview control inheriting from the existing winform TreeView control. Created a Load() function in the class TreeViewEx. In this function the dataSource is looped in a foreach. This foreach then calls the Where() extension method on the looping dataSource passing to it a methode (which takes as parameter the current element) returning a predicate. This predicate misintepretes the parameter value passed to it. It seems to be using previous parameter values.

value of arg in method before returning predicate => Image[^]

value of arg when debugger enters predicate => Image[^]

What I have tried:

Initially i thought this behavior was due to the fact that i am iterating through an Enumerable not a list, so i change the different enumerables to List but nothing changed. Also tried to instatiate the returned predicate but nothing.

Load function :


C#
public Func<T, Func<T, bool>> GetChildrenPredicate { get; set; }
.
.
.
public virtual void Load(List<T> dataSource = null)
{
    try
    {
        if (CreateNode == null)
        {
            OnError?.Invoke(this, new ArgumentNullException("CreateNode"));
            return;
        }
        if (GetParentKey == null)
        {
            OnError?.Invoke(this, new ArgumentNullException("GetParentKey"));
            return;
        }
        if (GetChildrenPredicate == null)
        {
            OnError?.Invoke(this, new ArgumentNullException("GetChildrenPredicate"));
            return;
        }

        var finalDataSource = dataSource ?? DataSource;

        TreeNode node = null;
        BeginUpdate();
        foreach (var item in finalDataSource)
        {
            node = CreateNode(item);
            node.Tag = item;

            if (this.Nodes.Find(node.Name, true).Count() == 0)
            {
                var n = this.Nodes.Find(this.GetParentKey(item), true).FirstOrDefault() as TreeNode;

                if (n == null)
                {
                    this.Nodes.Add(node);
                }
                else
                {
                    n.Nodes.Add(node);
                }

                List<T> children = finalDataSource
                                  .ToList()                                   
                                  .Where(this.GetChildrenPredicate(item))
                                  .ToList(); //this.GetChildrenPredicate is
                                //the property func generating the 
                                //predicate set by a different class

                if (children.Count() > 0)
                {
                    // Recursively call this function for all childRows
                    Load(children);
                }

            }
        }
        EndUpdate();
    }
    catch (Exception ex)
    {
        OnError?.Invoke(this, ex);
    }
}


GetChildrenPredicate :

C#
private Func<ORM.DataModels.Menu, bool> GetChildrenPredicate(ORM.DataModels.Menu arg)
{

    return (ORM.DataModels.Menu m) =>
    (m.Lepere == arg.Codmen) ||
    (m.Lepere == null && arg.Codmen == "_" + m.Niveau);
}
Posted
Updated 8-Apr-19 6:19am
Comments
[no name] 8-Apr-19 10:06am    
I build my own custom treeviews (WPF, UWP) using a sorted list of items, a listview, a level #, and about 30 lines of spaced code.

I would say yours is over-engineered; assuming it ever works and can be maintained.
bugMaker-237 8-Apr-19 10:28am    
My treeview is in winform and is generic. So it relies on exteranl methods and events set by the controller. If you think it can be ameliorated i am opened to any suggestion.

1 solution

Ok. I found the solution. Actually i did not realized that `finalDataSource` was overriden on each call of `Load()`. I was only focused on the weird behaviour of the predicate. just had to used the global DataSource property defined in the class.


C#
List<T> children = this.DataSource.Where(this.GetChildrenPredicate(item)); //<= changed local variable finalDataSource to the defined property this.DataSource
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900