Welcome Guest Search | Active Topics | Sign In | Register

Treeview Incorrect custom attributes Options
Aaron Trowell
Posted: Thursday, May 7, 2009 11:30:35 AM
Rank: Member
Groups: Member

Joined: 10/9/2008
Posts: 9
Hi,

I'm experiencing some strange problems when usign the treeview. I'm binding the treeview to an XML document which appears fine on the surface as the node text is correct, however when I select a node, i'm examining NavigationItem.DataItem in the ItemClicked event as I need to obtain various values from the custom attributes... but it seems to have loaded the attributes to the child node instead.

For example in the attached xml if i click on node 1 (empty) the attributes i would get are from node m012b.

Is there a problem with my XML? All relevant code is below. I have a developers key which I can PM to you.

Many Thanks,

Aaron

Code: C#
protected void TreeView_ItemDataBound(object sender, EO.Web.NavigationItemEventArgs e)
        {
            String NodeText = null;
            EO.Web.ElementStyle SelectedNodeStyle = new EO.Web.ElementStyle();

            //RaiseServerEventonClick.

            if (e.TreeNode.Text != null)
            {
                // Set Node Text
                NodeText = ((System.Xml.XmlLinkedNode)e.TreeNode.DataItem).Attributes["Name"].Value.Replace("+", "");

                e.TreeNode.Text = NodeText;

                e.TreeNode.RaisesServerEvent = EO.Web.NullableBool.True;

                //Set Node Image
                switch (int.Parse(((System.Xml.XmlLinkedNode)e.TreeNode.DataItem).Attributes["Type"].Value))
                {
                    case (int)eAttributeNodeType.Journal:
                        e.TreeNode.ImageUrl = JournalNodeImagePath;
                        break;
                    case (int)eAttributeNodeType.Promotion:
                        e.TreeNode.ImageUrl = PromotionNodeImagePath;
                        break;
                    case (int)eAttributeNodeType.Dispatch:
                        e.TreeNode.ImageUrl = DispatchNodeImagePath;
                        break;
                    case (int)eAttributeNodeType.Country:
                        e.TreeNode.ImageUrl = CountryNodeImagePath;
                        break;
                    case (int)eAttributeNodeType.Term:
                        e.TreeNode.ImageUrl = TermNodeImagePath;
                        break;
                    case (int)eAttributeNodeType.SubscriptionType:
                        e.TreeNode.ImageUrl = SubTypeNodeImagePath;
                        break;
                    case (int)eAttributeNodeType.Campaign:
                        e.TreeNode.ImageUrl = CampaignNodeImagePath;
                        break;
                    case (int)eAttributeNodeType.Supplier:
                        e.TreeNode.ImageUrl = SupplierNodeImagePath;
                        break;
                }

                // Set Node Style
                SelectedNodeStyle.CssClass = SelectedNodeCSS;
                e.TreeNode.SelectedStyle = SelectedNodeStyle;

            }            
        }


Code: C#
protected EO.Web.TreeView CreateTree()
        {
            EO.Web.TreeView attributeTree = new EO.Web.TreeView();
            AdminAttributeManagerControl AttributeManager = FindAdminManagerOnParent(this.Parent.Page.Master.Master.Master);
            XmlDocument TreeXml;
            XmlDataSource treeDataSource = new XmlDataSource();

            attributeTree.ItemDataBound += new EO.Web.NavigationItemEventHandler(TreeView_ItemDataBound);
            attributeTree.ItemClick += new EO.Web.NavigationItemEventHandler(TreeView_ItemClicked);

            if (AttributeManager != null)
            {
                var foundTree = from o in AttributeManager.ContentTrees
                                where o.AttributeID == this.AttributeID && o.ForestID == AttributeManager.ForestID
                                select o;


                if (foundTree.Count() > 0)
                {
                    if (foundTree.Count(x => x.ForestID == AttributeManager.ForestID) == 1 && foundTree.Count(x => x.AttributeID == this.AttributeID) == 1)
                    {
                        TreeXml = AttributeManager.GetTreeXML(foundTree.ElementAt(0).ID);

                        if (TreeXml.InnerXml != string.Empty)
                        {
                            attributeTree.ID = this.ID + "TreeView";
                            attributeTree.DataSource = treeDataSource;

                            treeDataSource.ID = this.ID + "DataSource";
                            treeDataSource.Data = TreeXml.InnerXml;
                            treeDataSource.XPath = "/*";
                            treeDataSource.DataBind();

                            attributeTree.DataBind();

                            attributeTree.ExpandAll();

                        }                         
                    }
                }                
            }

            return attributeTree;            
        }


Code: XML
- <Node1 Name="+(Empty)" Left="1" Right="4" NodeID="128" Type="8" Value="Parent Node Content" ContentID="56" Level="1">
  <Node2 Name="++m012b" Left="2" Right="3" NodeID="137" Type="2" Value="Child Node content" ContentID="55" Level="2" /> 
  </Node>


eo_support
Posted: Thursday, May 7, 2009 2:03:50 PM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,194
Hi,

The code you posted appears to be correct. I am not sure what exactly you mean by "the attributes i would get ...". There is no way for you to get the data source item when an item is clicked. DataItem is only avaialble during data binding, so once data binding is done, it will be null. That means by the time you click a TreeNode, it's already gone. So I am not sure how you get the attribute at that stage?

Thanks!
Aaron Trowell
Posted: Thursday, May 7, 2009 3:10:03 PM
Rank: Member
Groups: Member

Joined: 10/9/2008
Posts: 9
Hi,

Thanks for your very quick response. The Code below can read the attributes from the DataItem property of e.NavigationItem as long as I cast it to an XmlLinkedNode during an ItemClicked event.

In the example below, if I select the 'empty' node the content id returns 55 when in actual fact it should return 56. ContentID 55 relates to the node 'm012b'

I need to be able to access these attributes when the node is selected, if I shouldn't do it that way please could you provide me with a solution?

Many Thanks,

Aaron

Code: C#
protected void TreeView_ItemClicked(object sender, EO.Web.NavigationItemEventArgs e)
        {
            if (e.TreeNode != null)
            {
                int ContentID = 0;
                ContentID = int.Parse(((System.Xml.XmlLinkedNode)e.NavigationItem.DataItem).Attributes["ContentID"].Value);
            }
        }
eo_support
Posted: Thursday, May 7, 2009 3:18:18 PM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,194
Hi,

You should not use DataItem anywhwere outside of the data binding process (I am not sure how it actually has a value for you at all because it supposes to be null). The standard data binding process build the TreeView from your data source and then keep the tree but discard the data source. So once it is discarded, you can no longer access it from the TreeView.

In order for you to find out the original data item (an XmlElement in your case), you should store some kind of keys in your TreeView. The TreeView provides Value property specificially for this purpose. For example, many users who populate from a data table would usually store some kind of record ID in the Value property so that they can locate the record by that ID later. In your case, you will also need to have some kind of value stored in Value property so that you can later locate the corresponding xml element based on that value.

Thanks!
Aaron Trowell
Posted: Thursday, May 7, 2009 3:29:13 PM
Rank: Member
Groups: Member

Joined: 10/9/2008
Posts: 9
Hi,

That solution isn't really very elegant especially as the values i need (albeit incorrect) are there in the dataitem when that event is fired! Have you been able to run the code so you can see what I mean?.

Clearly this functionality is availble more by accident rather than design but I do feel that being able to store extra values in a node would be really cool, and it was actually the main reason why we chose your controls in the first place!

Thanks,

Aaron
eo_support
Posted: Thursday, May 7, 2009 3:43:26 PM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,194
Hi,

You can always store extra values in a node, that part has always been there. What I was trying to clarify is that it stores a simple value, not your whole data source.

It is not possible for the TreeView to keep the whole data set in a unified way because of many issues such as performance, serlizations and concurrency issues. Many user will gone mad if the TreeView automatically stores "unnecessary data" for them. Another situation is concurrent issue, for example, if we save a record in the TreeView and then when the page posts back but another user has already changed the reocrd, you would face a difficult situation on which data to use because the data saved in the TreeView is no longer accurate. All these issue add together would results in the "feature" causing more problem than it solves.

We have not been able to run your code because the code you provided is not complete. It relies on some other classes (for example, AdminAttributeManagerControl) that we do not have. But in any case, you should not expect DataItem to work outside of data binding. The sole purpose of that property is for you to populate your nodes.

Thanks!
Aaron Trowell
Posted: Thursday, May 7, 2009 3:54:58 PM
Rank: Member
Groups: Member

Joined: 10/9/2008
Posts: 9
Hi,

Concurrency would never have been a problem for us as this is for a CMS that only a very limited number of people would have access to. Those are very good points though.

Thanks anyway,

Aaron
Aaron Trowell
Posted: Thursday, May 7, 2009 4:12:05 PM
Rank: Member
Groups: Member

Joined: 10/9/2008
Posts: 9
Sounds like a bit of a bug with your treeview as it does automatically store "unnesseary data".

I have just created a test project which I can send which will demonstrate the issue to you if you like?

Aaron
eo_support
Posted: Thursday, May 7, 2009 4:16:12 PM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,194
Absolutely. We will PM you as to where to send.

Thanks!


You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.