Home - Forums-.NET - FlyTreeView (ASP.NET) - nodes not shown properly after code-behind add

FlyTreeView (ASP.NET)

Technical support and KB related to the FlyTreeView control

This forum related to following products: FlyTreeView for ASP.NET

nodes not shown properly after code-behind add
Link Posted: 17-Dec-2007 07:31
Hello,

Wow are you busy!  

My nodes are not getting displayed for code-behind programmatic populate.  Only root node with no child nodes are displayed when a second PostBack occurs.  Debug showed nodes added correctly.

  

Again, all nodes are not shown on PostBack.

I plan on using AJAX, but not until Server-Side populate works.

Your help would be appreciated.

Regards,
William Johnston
Link Posted: 17-Dec-2007 08:04
William,

As you can see from demos, there's Postback button to demonstrate that treeview keeps all its nodes between postbacks.

How do you populate treeview?  Any code appreciated.
Link Posted: 18-Dec-2007 04:34
Hope fully you are passing it by reference.

are you using for each to iterate through the nodes and then inserting ?
Link Posted: 18-Dec-2007 04:50
William,

There several ways to add nodes. But it does not depend, all you need is to have viewstate enabled.

Style demos like
http://www.9rays.net/asp.net_2/treeview/Demo_Classic.aspx
Iterates through filesystem and adds nodes one by one. Anyway it persists nodes between postbacks.
Link Posted: 18-Dec-2007 05:42
[quote="EvgenyT"]William,

As you can see from demos, there's Postback button to demonstrate that treeview keeps all its nodes between postbacks.

How do you populate treeview?  Any code appreciated.


Here is some code that populates the Tree:

        ///
        /// Extracts database data from an SQLDataReader.
        /// Displays information for the SqlStatements.SQLStatement18 command
        ///
        private void DisplayStatement12(SqlDataReader reader, bool bOutputData)
        {
            int prev_word_id = -1;
            int word_id = -1;
            int timestamp_id = -1;

            short prev_movie_id = -1;
            short movie_id = 1;

            string output = null;
            string url = null;
            string text = null;

            FlyTreeNode treeNode = new FlyTreeNode();
            FlyTreeNode treeNode2 = new FlyTreeNode();
            FlyTreeNode treeNode3 = new FlyTreeNode();

            ArrayList tempResultList = new ArrayList();

            try
            {

                if (reader.HasRows)
                {
                    if (dataSet2 == null)
                    {
                        dataSet2 = new DVDSearchDataSet();
                    }
                }
                else
                {
                    return;
                }
                //no result TreeNode added in ProcessSQLStatement

                while (reader.Read())
                {
                    object[] formatParams = new object[5];
                    formatParams[0] = reader.GetInt16(0);   //movie_id
                    formatParams[1] = reader.GetString(1);  //text
                    formatParams[2] = reader.GetString(2);  //url
                    formatParams[3] = reader.GetInt32(3);   //word_id
                    formatParams[4] = reader.GetInt32(4);   //timestamp_id - used for GetHashCode() method

                    movie_id = (short)formatParams[0];
                    text = (string)formatParams[1];
                    url = (string)formatParams[2];
                    word_id = (int)formatParams[3];
                    timestamp_id = (int)formatParams[4];

                    // Create DVDQueryInfo object
                    DVDQueryInfo dvdQueryInfo = new DVDQueryInfo(
                        movie_id,
                        word_id,
                        -1,
                        -1,
                        timestamp_id,
                        text,
                        url);


                    // Do not process duplicates.
                    // Add in reverse order.
                    if (!tempResultList.Contains(dvdQueryInfo))
                    {
                        // Add row to DVDSearchDataSet
                        dataSet2.AddRow(
                            movie_id,
                            word_id,
                            -1,
                            -1,
                            timestamp_id,
                            text,
                            url);

                        tempResultList.Insert(0, dvdQueryInfo);
                    }

                    if (bCreateTreeNodes)
                    {
                        // If new word
                        if (prev_word_id == -1 || prev_word_id != word_id)
                        {
                            treeNode = new FlyTreeNode();

                            object[] formatParams3 = new object[1];
                            formatParams3[0] = (string)dvdWordHash[word_id];
                            treeNode.Text = string.Format("\"{0}\"", formatParams3);
                            treeNode.ToolTip = "This is the DVD search word.";

                            rootNode.ChildNodes.Add(treeNode);

                            prev_word_id = word_id;
                        }

                        // If new movie
                        if (prev_movie_id == -1 || prev_movie_id != movie_id)
                        {
                            // Add movie title tree node
                            treeNode2 = new FlyTreeNode();
                            treeNode2.Text = (string)dvdTitles[(int)movie_id];
                            treeNode2.ToolTip = "This is a DVD title.";
                            treeNode.ChildNodes.Add(treeNode2);

                            prev_movie_id = movie_id;
                        }

                        text = string.Format("\"{0}\"", text);

                        treeNode3 = new FlyTreeNode();
                        treeNode3.Text = text;
                        treeNode3.ToolTip = "Double-click to view the video clip.";
                        treeNode3.NavigateUrl = CreateMoviePlayerURL(url);

                        treeNode2.ChildNodes.Add(treeNode3);
                    }

                    DVDResultCount++;
                }

                //add temp list (in insert order) to stack
                foreach (DVDQueryInfo dvdQueryInfo2 in tempResultList)
                {
                    //do not include/display duplicates
                    if (!results.Contains((object)dvdQueryInfo2))
                    {
                        //push onto stack here
                        results.Push(dvdQueryInfo2);
                    }
                }

            }
            catch (InvalidCastException ice)
            {
                output += "\n" + ice.Message + "\n";
                if (appendText != null)
                {
                    appendText(output);
                }
            }
            catch (Exception e)
            {
                output += "\n" + e.Message + "\n";
                if (appendText != null)
                {
                    appendText(output);
                }
            }
        }


I am fairly certain that the populate code is correct.  The rootNode variable is added prior to function invocation.

Again, I am passing my FlyTreeView object not by reference, and to a static variable.  This is probably the error.

Reason being is that I cannot pass the ViewState Property by reference.

Thanks,
William Johnston
Link Posted: 18-Dec-2007 05:59
[quote="hellowahab"]Hope fully you are passing it by reference.

are you using for each to iterate through the nodes and then inserting ?


No, I use the SqlDataReader.Read() boolean in a while loop.

Please see the above reply.

This is my Page_Load method which creates an InstructionProc object.

        protected void Page_Load(object sender, System.EventArgs e)
        {
//            FlyTreeView1.Attributes["IsMovieList"] = "true";

            instructionProc = new InstructionProc(this.ViewState, this.FlyTreeView1, true);

            //set group number by day.
            instructionProc.SetGroupNumber();

            // Put user code to initialize the page here
            if (!IsPostBack)
            {
                //load Menu items
                Menu1.DataSource = Server.MapPath(xmlFileName);
                Menu1.DataBind();

                string wallpaper = LoadWallPaper();
                Body1.Attributes["background"] = wallpaper;

                DisplayPrompt();
                instructionProc.GetBookTitles();
                instructionProc.GetDVDTitles();
                LoadBookTitles(true);
                LoadDVDTitles(true);
                bLoadedTitles = true;
                LoadTreeView();
                DisplayPrompt();
            }
            if (!bLoadedTitles)
            {
                LoadBookTitles(false);
                LoadDVDTitles(false);
            }
        }


The code below populates the TreeView correctly and is located in the Form class.  I cannot populate nodes correctly from the InstructionProc class:

        ///
        /// loads book titles into TreeView from ViewState
        ///
        ///
        private void LoadTreeView()
        {
            FlyTreeNode rootNode = new FlyTreeNode();
            FlyTreeNode rootNode2 = new FlyTreeNode();
            FlyTreeNode treeNode = new FlyTreeNode();

            rootNode.Text = "Books";
            rootNode.ToolTip = "This is the list of searchable books.";
            FlyTreeView1.Nodes.Add(rootNode);

            ArrayList tempList = new ArrayList();

            IDictionaryEnumerator iterator = instructionProc.BookTitles.GetEnumerator();
            while (iterator.MoveNext())
            {
                tempList.Add((string)iterator.Value);
            }

            tempList.Sort();

            foreach (string bookTitle in tempList)
            {
                treeNode = new FlyTreeNode();
                treeNode.Text = bookTitle;
                rootNode.ChildNodes.Add(treeNode);
            }

            rootNode2.Text = "DVDs";
            rootNode2.ToolTip = "This is the list of searchable DVDs.";
            FlyTreeView1.Nodes.Add(rootNode2);

            tempList.Clear();

            iterator = instructionProc.DVDTitles.GetEnumerator();
            while (iterator.MoveNext())
            {
                tempList.Add((string)iterator.Value);
            }

            tempList.Sort();

            foreach (string dvdTitle in tempList)
            {
                treeNode = new FlyTreeNode();
                treeNode.Text = dvdTitle;
                rootNode2.ChildNodes.Add(treeNode);
            }
        }



Thanks,
William Johnston
Link Posted: 18-Dec-2007 06:07
[quote="EvgenyT"]William,

There several ways to add nodes. But it does not depend, all you need is to have viewstate enabled.

Style demos like
http://www.9rays.net/asp.net_2/treeview/Demo_Classic.aspx
Iterates through filesystem and adds nodes one by one. Anyway it persists nodes between postbacks.


My nodes are still not displayed even with FlyTreeView.EnableViewState set to true.

No new nodes are displayed on PostBack.  And only partial Tree with new nodes shown on a second PostBack.

Insert code is shown in first reply.

Thanks,
William Johnston
Link Posted: 18-Dec-2007 07:03
William,

If you replace your LoadTreeView code with something very simple like:
private void LoadTreeView()
{
    FlyTreeNode rootNode = new FlyTreeNode("Node");
    FlyTreeView1.Nodes.Add(rootNode);
}


Do you still experience problems?


Generally, everything like this should work:
Page_Load:

protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        // like this
        FlyTreeNode rootNode = new FlyTreeNode("Node");
        FlyTreeView1.Nodes.Add(rootNode);
        ....
        // or like this
        FlyTreeView1.DataSource = yourHierarchicalData;
        FlyTreeView1.DataBind();
    }
}

It's no matter how you create nodes, if viewstate is enabled, they are persisted between postbacks.
Link Posted: 18-Dec-2007 09:54
[quote="EvgenyT"]William,

If you replace your LoadTreeView code with something very simple like:
private void LoadTreeView()
{
    FlyTreeNode rootNode = new FlyTreeNode("Node");
    FlyTreeView1.Nodes.Add(rootNode);
}


Do you still experience problems?


Generally, everything like this should work:
Page_Load:

protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        // like this
        FlyTreeNode rootNode = new FlyTreeNode("Node");
        FlyTreeView1.Nodes.Add(rootNode);
        ....
        // or like this
        FlyTreeView1.DataSource = yourHierarchicalData;
        FlyTreeView1.DataBind();
    }
}

It's no matter how you create nodes, if viewstate is enabled, they are persisted between postbacks.


I am still experiencing problems when adding a parameter to the FlyTreeNode constructor.

Why Web app is AJAX enabled and has a nested class that runs a long-running thread.  Can a FlyTreeView be a static variable?  The nested class needs to set the instance of the FlyTreeView variable.

As of now I pass a reference of FlyTreeView to the constructor.  My question is, does the nested class variable maintain the reference?  Perhaps that is why the Tree is not being updated?

Here is the nested constructor code:

       public class ThreadProc : ITask
        {
            private FlyTreeView FlyTreeView1 = null;

            public ThreadProc(ref FlyTreeView FlyTreeView11)
            {
                FlyTreeView1 = FlyTreeView11;
            }
            ...
        }



I then call the Start method from a thread handler:

            public void Start()
            {
                m_Finished = false;
                m_hasError = false;

                //Record the Start Time
                m_startTime = DateTime.Now;

                //Setup Basic Error Handling
                try
                {
                    m_Instance.RunQueries(InstructionProcList, ref FlyTreeView1);
                }
                catch (Exception ex)
                {
                    m_hasError = true;
                    m_statusDescription = ex.ToString();
                }
      
                m_FinishTime = DateTime.Now;
                m_Finished = true;
            }


The m_instance variable is static.

What do you think?

Thanks,
William Johnston
Link Posted: 18-Dec-2007 20:19
Why you want flyTreeView be a static variable. Simply you have to pass the reference of the control you have got on your page. The thread or function simply have access to that contol or surely populate it. Or if you are having your function on the same page all you need is, to access the control directly.

Simply pass the reference of control. Not a temporary variable


            public class ThreadProc : ITask
            {

private FlyTreeView FlyTreeView1 = null;

                public ThreadProc(ref FlyTreeView FlyTreeView11)
                {
                    FlyTreeView1 = FlyTreeView11;
                }
                ...
            }


simply pass the control on your page, and code should be like that


           public class ThreadProc : ITask
            {

                //---------------private FlyTreeView FlyTreeView1 = null;

                public ThreadProc(ref FlyTreeView FlyTreeView11)
                {
                    FlyTreeView1 = FlyTreeView11;
                }

private void DoSomeTask()
{
ThreadProc(FlyTreeView1);   //FlyTreeView1 being you control on web page
}


            }