I need to dynamically generate several treeview on my code and I want to be able to load nodes on demand. I have below code structures. My problem is SelectedNodeChanged event for populated TreeView node will not fire. Once you run below code sample, if you expand child node to several level and then click the child node, the label will not show text and the populated nodes collapse. Any idea is appreciated!
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class TreeViewTest : System.Web.UI.Page
{
private const int Count = 2;
private string[] codeList = { "th", "os" };
protected void Page_Load(object sender, EventArgs e)
{
updateTree();
}
protected void updateTree()
{
treePanel.Controls.Clear();
TreeView[] treeList = new TreeView[Count];
for (int i = 0; i < Count; i++)
{
var tree = new TreeView();
tree.ID = "treelist" + i.ToString();
tree.TreeNodePopulate += TreeBranch_SelectedNodePopulate;
tree.SelectedNodeChanged += TreeBranch_SelectedNodeChanged;
string codeName = codeList[i];
TreeNode codeNode = new TreeNode(codeName, codeName);
codeNode.SelectAction = TreeNodeSelectAction.Select;
codeNode.PopulateOnDemand = true;
tree.Nodes.Add(codeNode);
tree.ExpandDepth = 2;
treePanel.Controls.Add(tree);
treeList[i] = tree;
}
}
protected void TreeBranch_SelectedNodeChanged(object sender, EventArgs e)
{
TreeView treeview = (TreeView)sender;
string text = treeview.SelectedNode.Text;
Label1.Text = text;
}
protected void TreeBranch_SelectedNodePopulate(object sender, TreeNodeEventArgs e)
{
LoadChildNode(e.Node);
}
public void LoadChildNode(TreeNode parentNode)
{
TreeNode childNode = new TreeNode("childNode","childNode");
parentNode.ChildNodes.Add(childNode);
childNode.PopulateOnDemand = true;
}
}
Try the following code.
treePanel.Controls.Clear();
TreeView[] treeList = new TreeView[codebaseCount]; //But I recommend you use List<TreeView> instead of TreeView[];
for (int i = 0; i < codebaseCount; i++)
{
var tree = new TreeView();
tree.ID = "treelist" + i.ToString();
tree.TreeNodePopulate += TreeBranch_SelectedNodePopulate;
tree.SelectedNodeChanged += TreeBranch_SelectedNodeChanged;
TreeNode newNode = new TreeNode(newName,newName);
newNode.SelectAction = TreeNodeSelectAction.None;
newNode.Expand();
tree.Nodes.Add(newNode);
tree.ExpandDepth = 2;
treePanel.Controls.Add(tree);
treeList[i] = tree;
// more code ...
}
Related
Every time when I click the button only one row will be displayed. But it should show multiple rows. I declare the list after the constructor invoke. I tried with gridview.update() and gridview.refresh() but they didn't work. I could not findout the issue.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using JournalEntryApp.Model;
namespace JournalEntryApp
{
public partial class NewDocument : Form
{
public NewDocument()
{
InitializeComponent();
}
List<JEFrom> JEFromsList = new List<JEFrom>();
List<JETo> JETosList = new List<JETo>();
JEFrom _jef = null;
private void NewDocument_Load(object sender, EventArgs e)
{
label4.Text = DateTime.Now.ToString("dd-MMM-yyyy");
using (var db =new JournalContext())
{
unitComboBox.DataSource = db.Units.ToList();
unitComboBox.ValueMember = "Id";
unitComboBox.DisplayMember = "UnitName";
}
}
private void addToListButton_Click(object sender, EventArgs e)
{
if (string.Empty== fromAccountTextBox.Text)
{
MessageBox.Show("From Account can not be empty!!!");
}
else if (string.Empty == toAccountTextBox.Text)
{
MessageBox.Show("To Account can not be empty!!!");
}
else
{
_jef = new JEFrom{ FromEntryName= fromAccountTextBox.Text , FromEntryDate= DateTime.Now };
JEFromsList.Add(_jef);
temporaryDataGridView.DataSource = JEFromsList;
fromAccountTextBox.Text = string.Empty;
toAccountTextBox.Text = string.Empty;
}
}
}
}
The temporaryDataGridView cannot detect that you have changed the DataSource. It will only refresh when Datasource has changed.
temporaryDataGridView.DataSource = null;
temporaryDataGridView.DataSource = JEFromsList;
so change the Datasource null first.
Or you can use bindingSource
private void NewDocument_Load(object sender, EventArgs e)
{
this.bindingSource1.DataSource = JEFromsList;
temporaryDataGridView.DataSource = this.bindingSource1;
label4.Text = DateTime.Now.ToString("dd-MMM-yyyy");
using (var db =new JournalContext())
{
unitComboBox.DataSource = db.Units.ToList();
unitComboBox.ValueMember = "Id";
unitComboBox.DisplayMember = "UnitName";
}
}
in button_click
JEFromsList.Add(_jef);
bindingSource1.ResetBindings(true);
I have created a Winform. I want to show Subanatomy ID information using object of type Subanatomy after the node is selected how Should I do it.?
i have used all the neccessary libraries in my original code
` using System.Windows.Forms;
using basicObjectLib;
namespace WindowsFormsApplication12
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
LoadTreeItems();
}
public void LoadTreeItems()
{
// Dummy Data
// created a DLL Basic Class Object Conatining class definitions of anatomy subanatomy
#region Object
Anatomy an1 = new Anatomy();
an1.AnatomyID = 1;
an1.AnatomyName = "Anatomy1";
Subanatomy san1 = new Subanatomy();
san1.SubAnatomyID = 11;
san1.SubAnatomyName = "subAn1";
an1.SubanatomyList.Add(san1);
Subanatomy san2 = new Subanatomy();
san2.SubAnatomyName = "subAn2";
san2.SubAnatomyID = 2;
an1.SubanatomyList.Add(san2);
Anatomy an2 = new Anatomy();
an2.AnatomyID = 2;
an2.AnatomyName = "Anatomy2";
Subanatomy san21 = new Subanatomy();
san21.SubAnatomyName = "subAn1";
san21.SubAnatomyID = 21;
an2.SubanatomyList.Add(san21);
Subanatomy san22 = new Subanatomy();
san22.SubAnatomyName = "subAn2";
san22.SubAnatomyID = 22;
an2.SubanatomyList.Add(san22);
Anatomy an3 = new Anatomy();
an3.AnatomyID = 3;
an3.AnatomyName = "Anatomy3";
Subanatomy san31 = new Subanatomy();
san31.SubAnatomyName = "subAn1";
san31.SubAnatomyID = 31;
an3.SubanatomyList.Add(san31);
Subanatomy san32 = new Subanatomy();
san32.SubAnatomyName = "subAn2";
san32.SubAnatomyID = 32;
an3.SubanatomyList.Add(san32);
List<Anatomy> anatomyObj = new List<Anatomy>();
anatomyObj.Add(an1);
anatomyObj.Add(an2);
anatomyObj.Add(an3);
#endregion
foreach(Anatomy obj in anatomyObj)
{
TreeNode parentNode = new TreeNode();
parentNode = new TreeNode(obj.AnatomyName);
treeView1.Nodes.Add(parentNode);
foreach(Subanatomy subObj in obj.SubanatomyList)
{
TreeNode childNode = new TreeNode();
childNode = new TreeNode(subObj.SubAnatomyName);
parentNode.Nodes.Add(childNode);
}
}
}
private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
{
if (e.Action == TreeViewAction.ByMouse)
{
// name of treeNode
textBox4.Text = treeView1.SelectedNode.Name.ToString();
// to show the ID
textBox2.Text = "";
}
}
private void button1_Click(object sender, EventArgs e)
{
treeView1.ExpandAll();
}
}
public class WindowsFormApplication
{
public static void main()
{
Form1 _treeviewDemo = new Form1();
}
}
}`
you can use TreeNode.Tag to store your object.
when you create a TreeNode, assign the object you want to associate it with to the TreeNode Example:
treeNode.Tag=<object>
you can use it later by casting it
Example:
(<Class>)treeNode.Tag
In your code:
foreach(Subanatomy subObj in obj.SubanatomyList)
{
TreeNode childNode = new TreeNode();
childNode = new TreeNode(subObj.SubAnatomyName) { Tag = subjObj.SubAnatomyID };
parentNode.Nodes.Add(childNode);
}
and get data
private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
{
if (e.Action == TreeViewAction.ByMouse)
{
// name of treeNode
textBox4.Text = treeView1.SelectedNode.Name.ToString();
// to show the ID
textBox2.Text = ((int)treeView1.SelectedNode.Tag).ToString();
}
}
But I think better is
foreach(Subanatomy subObj in obj.SubanatomyList)
{
TreeNode childNode = new TreeNode();
childNode = new TreeNode(subObj.SubAnatomyName) { Tag = subjObj };
parentNode.Nodes.Add(childNode);
}
and
private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
{
if (e.Action == TreeViewAction.ByMouse)
{
Subanatomy suba = treeView1.SelectedNode.Tag as Subanatomy;
if (suba != null)
{
// name of treeNode
textBox4.Text = subA.SubAnatomyName;
// to show the ID
textBox2.Text = subA.SubAnatomyID.ToString();
}
}
}
Im at beginner level and have tried for a while now. Im trying to remove an item from a ListBox with the help of a remove button. The code is not giving away any errors but the items is not disappearing from the list.
This is the part im struggling with
void taBort()
{
listboxKontakter.SelectedItems.Remove(listboxKontakter.SelectedItems);
textboxAnteckningar.Clear();
textboxGatuadress.Clear();
textboxNamn.Clear();
textboxPostnummerOrt.Clear();
textboxEmail.Clear();
textboxFödelsedag.Value = DateTime.Now;
}
Here is my entire code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace adressboken
{
public partial class Form1 : Form
{
List<Kontakter> kontaktLista = new List<Kontakter>();
Kontakter person;
string path = "kontakter.txt";
public Form1()
{
InitializeComponent();
}
private void LäggTill_Click(object sender, EventArgs e)
{
person = new Kontakter();
person.FullständigtNamn = textboxNamn.Text;
person.Gatuadress = textboxGatuadress.Text;
person.PostnummerOrt = textboxPostnummerOrt.Text;
person.Födelsedag = textboxFödelsedag.Value;
person.Email = textboxEmail.Text;
person.Anteckningar = textboxAnteckningar.Text;
kontaktLista.Add(person);
listboxKontakter.DataSource = null;
listboxKontakter.DisplayMember = "FullständigtNamn";
listboxKontakter.DataSource = kontaktLista;
textboxAnteckningar.Clear();
textboxGatuadress.Clear();
textboxNamn.Clear();
textboxPostnummerOrt.Clear();
textboxEmail.Clear();
textboxFödelsedag.Value = DateTime.Now;
textboxAntal.Text = kontaktLista.Count.ToString();
}
private void Rensa_Click(object sender, EventArgs e)
{
textboxAnteckningar.Clear();
textboxGatuadress.Clear();
textboxNamn.Clear();
textboxPostnummerOrt.Clear();
textboxEmail.Clear();
textboxFödelsedag.Value = DateTime.Now;
}
void taBort()
{
textboxAnteckningar.Clear();
textboxGatuadress.Clear();
textboxNamn.Clear();
textboxPostnummerOrt.Clear();
textboxEmail.Clear();
textboxFödelsedag.Value = DateTime.Now;
}
private void Form1_Load(object sender, EventArgs e)
{
kontaktLista = new List<Kontakter>();
string line = "";
StreamReader sr = new StreamReader(path);
while ((line = sr.ReadLine()) != null)
{
string[] listarray = line.Split(',');
person = new Kontakter();
person.FullständigtNamn = listarray[0];
person.Gatuadress = listarray[1];
person.PostnummerOrt = listarray[2];
person.Email = listarray[3];
person.Födelsedag = Convert.ToDateTime(listarray[4]);
person.Anteckningar = listarray[5];
kontaktLista.Add(person);
}
sr.Close();
listboxKontakter.DataSource = kontaktLista;
listboxKontakter.DisplayMember = "FullständigtNamn";
}
public void listboxKontakter_Click(object sender, EventArgs e)
{
person = (Kontakter)listboxKontakter.SelectedItem;
textboxNamn.Text = person.FullständigtNamn;
textboxGatuadress.Text = person.Gatuadress;
textboxPostnummerOrt.Text = person.PostnummerOrt;
textboxEmail.Text = person.Email;
textboxFödelsedag.Value = person.Födelsedag;
var selectedindex = listboxKontakter.SelectedItems;
}
private void Spara_Click(object sender, EventArgs e)
{
StreamWriter sw = new StreamWriter(path);
foreach (Kontakter k in kontaktLista)
{
sw.WriteLine(k.FullInfo);
}
sw.Close();
}
private void taBortToolStripMenuItem_Click(object sender, EventArgs e)
{
taBort();
}
private void TaBort_Click(object sender, EventArgs e)
{
taBort();
}
}
}
Your code seems to remove all selected items, and does not refresh.
How about:
listboxKontakter.SelectedItems.Remove(listboxKontakter.SelectedItem);
listboxKontakter.Refresh();
You remove only the single selected item, then refresh your listbox.
If you want to remove ALL items try:
listboxKontakter.Items.Clear();
If you use a DataSource try:
listboxKontakter.DataSource = null;
If all else fails you could loop through the collection and RemoveAt:
for(int i=listboxKontakter.Items.Count; i > -1; i--) {
{
listboxKontakter.Items.RemoveAt(i);
}
Based on a bit of chatting, this should work for you:
void taBort()
{
var newList = (List<Kontakter>)listboxKontakter.DataSource;
var ds = newList.Where(k => k.FullständigtNamn != ((Kontakter)listboxKontakter.SelectedItem).FullständigtNamn).ToList();
listboxKontakter.DataSource = ds;
listboxKontakter.DisplayMember = "FullständigtNamn";
textboxAnteckningar.Clear();
textboxGatuadress.Clear();
textboxNamn.Clear();
textboxPostnummerOrt.Clear();
textboxEmail.Clear();
textboxFödelsedag.Value = DateTime.Now;
}
If you want to remove several items at once try:
var ds = newList.Where(k => !listboxKontakter.SelectedItems.Contains(k.FullständigtNamn)).ToList();
How about:
listboxKontakter.Items.Remove(itemthatneedstoberemoved)
and
listboxKontakter.Items.Clear();
(I assume you called the listbox, listboxKontakter?)
:
Take a look at this
.SelectedItems is basically just an array list of what items you have selected, so you will need to access those like this .SelectedItems[0] .SelectedItems[1].
However the above code even with the [0], [1] will only remove them from the selected list not the actual list box.
If you want to remove them from the list box you need to use the .Items.Remove call.
while(listboxKontakter.SelectedItems.Count >0)
{
listboxKontakter.Items.Remove(listboxKontakter.SelectedItems[0]);
}
EDIT:
If it is a single select listbox all you have to do is
listboxKontakter.Items.Remove(listboxKontakter.SelectedItem);
I want to make a RSS reader which makes it possible to get multiple news feeds at the same time, without my application "freezing" while getting the feed. To do this, I want some of the code to run in a seperate thread. I have tried some different things, to make it run in a seperate thread, but I keep getting exceptions. My code looks like this atm:
namespace NewsReader
{
public partial class Form1 : Form
{
XmlTextReader rssReader;
XmlDocument rssDoc;
XmlNode nodeRss;
XmlNode nodeChannel;
XmlNode nodeItem;
ListViewItem rowNews;
public Form1()
{
InitializeComponent();
}
private void btnRead_Click(object sender, EventArgs e)
{
//Creates a XmlTextReader which reads from the url entered in input field
rssReader = new XmlTextReader(txtUrl.Text);
//Creates an xml doc to save the content of the entered path
rssDoc = new XmlDocument();
//Loads the xml content from the reader into a XmlDocument
rssDoc.Load(rssReader);
//Make a loop to search for the <rss> tag
for (int i = 0; i < rssDoc.ChildNodes.Count; i++)
{
//If the childenode is the rss tag
if (rssDoc.ChildNodes[i].Name == "rss")
{
//the <rss> tag is found, and we know where it is
nodeRss = rssDoc.ChildNodes[i];
}
}
//Make a loop to search for the <channel> tag
for (int i = 0; i < nodeRss.ChildNodes.Count; i++)
{
//If the childnode is the channel tag
if (nodeRss.ChildNodes[i].Name == "channel")
{
//The channel tag is found and we know where it is
nodeChannel = nodeRss.ChildNodes[i];
}
}
//Make a loop to search for the <item> tag
for (int i = 0; i < nodeChannel.ChildNodes.Count; i++)
{
//If the childnode is the item tag
if (nodeChannel.ChildNodes[i].Name == "item")
{
//the item tag is found, and we know where it is
nodeItem = nodeChannel.ChildNodes[i];
//Creates a new row in the LstView which contains information from inside the nodes
rowNews = new ListViewItem();
rowNews.Text = nodeItem["title"].InnerText;
rowNews.SubItems.Add(nodeItem["link"].InnerText);
lstView.Items.Add(rowNews);
}
}
}
}
}
Does anyone have some examples of how to handle this problem? Code examples with my code is very appreciated :)
Thanks in advance.
You may checkout the BackgroundWorker class. And here's an example:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows.Forms;
using System.Xml.Linq;
using System.Xml.XPath;
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
backgroundWorker1.RunWorkerAsync(txtUrl.Text);
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
var rssDoc = XDocument.Load((string)e.Argument);
var items = new List<ListViewItem>();
foreach (var item in rssDoc.XPathSelectElements("//item"))
{
var listItem = new ListViewItem();
listItem.Text = item.Element("title").Value;
listItem.SubItems.Add(item.Element("link").Value);
items.Add(listItem);
}
e.Result = items.ToArray();
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
lstView.Items.AddRange((ListViewItem[])e.Result);
}
}
If you're using .NET 3.5 or later you can use the SyndicationFeed type to make parsing the RSS feed easier.
I'm adapting Darin Dimitrov's code example here:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows.Forms;
using System.ServiceModel.Syndication;
using System.Xml.Linq;
using System.Xml.XPath;
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
backgroundWorker1.RunWorkerAsync(txtUrl.Text);
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
var reader = new XmlTextReader((string)e.Argument);
var feed = SyndicationFeed.Load(reader);
var items = new List<ListViewItem>();
foreach (var item in feed.Items)
{
var listItem = new ListViewItem();
listItem.Text = item.Title;
foreach (var link in item.Links)
{
listItem.SubItems.Add(link.Uri.AbsoluteUri);
}
items.Add(listItem);
}
e.Result = items.ToArray();
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
lstView.Items.AddRange((ListViewItem[])e.Result);
}
}
If you are using .net 4.0 you can use the Task system for an even easier approach, and possibly better performance.
foreach (var item in rssDoc.XPathSelectElements("//item"))
{
Task fetch = new Task(() =>
{
// Go to server and get data....
// Add Data to UI...
});
fetch.Start();
}
The main benefit here is the Task system will decide how and when to run each fetch operation. In theory each operation will run in its own thread, so one or more at a time will be active instead of just one that you would see in a normal loop. The system is nice enough to do some load balancing for you too.
I am trying to dynamically add controls to an asp.net page. The page is rendering correctly but after posting back, I get the following error:
[HttpException (0x80004005): Multiple controls with the same
ID 'ParentTextBox_ChildTextBox_TV_PostRender' were found. FindControl requires that controls have unique IDs.]
System.Web.UI.Control.FillNamedControlsTable(Control namingContainer, ControlCollection controls) +273
System.Web.UI.Control.EnsureNamedControlsTable() +61
System.Web.UI.Control.FindControl(String id, Int32 pathOffset) +222
System.Web.UI.Control.FindControl(String id, Int32 pathOffset) +327
System.Web.UI.Page.FindControl(String id) +38
System.Web.UI.Page.ProcessPostData(NameValueCollection postData, Boolean fBeforeLoad) +232
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +1434
I have tried several different things a none of which work. I thought removing the control in OnInit or on page_load like this
Control c = Page.FindControl("ParentTextBox_ChildTextBox_TV_PostRender");
Page.Controls.Remove(c);
will work but it doesn't
Code of custom tree view control
// file ContainerTreeView.cs
using System.Web.UI;
using System.Web.UI.WebControls;
using System;
namespace DASHBOARD
{
[ToolboxData("<{0}:ContainerTreeView runat=server></{0}:ContainerTreeView>")]
public class ContainerTreeView : TreeView, INamingContainer
{
public ContainerTreeView()
: base()
{
PathSeparator = ClientIDSeparator;
}
protected override void OnInit(EventArgs e)
{
// Initialize Child Controls
RecurseUpdateNodes(Nodes);
base.OnInit(e);
}
protected const String s_strNodeValueSeparator = "_TV_";
protected virtual void RecurseUpdateNodes(TreeNodeCollection parrNodes)
{
if (parrNodes == null || parrNodes.Count == 0)
return;
foreach (TreeNode pNode in parrNodes)
{
ContainerTreeNode pContainerNode = pNode as ContainerTreeNode;
if (pContainerNode != null)
{
// update node pre / post rendering control IDs id
if (pContainerNode.PreRenderContainer != null)
{
pContainerNode.PreRenderContainer.ID = pContainerNode.PreRenderContainer.ID.Insert(0, pNode.ValuePath + s_strNodeValueSeparator);
Controls.Add(pContainerNode.PreRenderContainer);
}
if (pContainerNode.PostRenderContainer != null)
{
pContainerNode.PostRenderContainer.ID = pContainerNode.PostRenderContainer.ID.Insert(0, pNode.ValuePath + s_strNodeValueSeparator);
Controls.Add(pContainerNode.PostRenderContainer);
}
}
// update children
RecurseUpdateNodes(pNode.ChildNodes);
}
}
public ContainerTreeNode CreateTreeNode()
{
return new ContainerTreeNode(this, false);
}
protected override TreeNode CreateNode()
{
return CreateTreeNode();
}
// collection of child controls
protected override ControlCollection CreateControlCollection()
{
return new ControlCollection(this);
}
protected override void RenderChildren(HtmlTextWriter writer)
{
// do not render children as they will be rendered within treeview nodes
// base.RenderChildren(writer);
}
}
}
This is the page where I am adding the tree:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.Xml.Linq;
namespace DASHBOARD
{
public partial class testTreeEdit : System.Web.UI.Page
{
ContainerTreeView m_pTreeView = null;
protected override void OnInit(EventArgs e)
{
Control c = Page.FindControl("ParentTextBox_ChildTextBox_TV_PostRender");
Page.Controls.Remove(c);
tb.Text += "Removed Control";
base.OnInit(e);
}
#region main
protected void Page_Load(object sender, EventArgs e)
{
if (CheckBox1.Checked)
{
renderEditTree();
}
else
{
makeTree();
TreeView1.ExpandAll();
}
}
#endregion
#region editableTreeView
/** //function to render editable tree view
protected void renderEditTree()
{
m_pTreeView = new ContainerTreeView();
ContainerTreeNode pNodeParent = m_pTreeView.CreateTreeNode();
pNodeParent.Value = "Parent";
pNodeParent.Text = "Parent";
pNodeParent.Expanded = true;
m_pTreeView.Nodes.Add(pNodeParent);
/**ContainerTreeNode pNodeChildDropDown = m_pTreeView.CreateTreeNode();
pNodeChildDropDown.Value = "ChildDropDown";
pNodeChildDropDown.Text = String.Empty;
DropDownList pList = new DropDownList();
pList.ID = "ID_DropDown";
pList.Items.Add("AAA");
pList.Items.Add("BBB");
pList.Items.Add("CCC");
pNodeChildDropDown.PostRenderControls.Add(pList);
pNodeParent.ChildNodes.Add(pNodeChildDropDown);
/**ContainerTreeNode pNodeChildButton = m_pTreeView.CreateTreeNode();
pNodeChildButton.Value = "ChildButton";
pNodeChildButton.Text = String.Empty;
Button pButton = new Button();
pButton.ID = "ID_Button";
pButton.Text = "PostBack";
pNodeChildButton.PostRenderControls.Add(pButton);
pNodeParent.ChildNodes.Add(pNodeChildButton);
/** ContainerTreeNode pNodeChildTextBox = m_pTreeView.CreateTreeNode();
pNodeChildTextBox.Value = "ChildTextBox";
pNodeChildTextBox.Text = String.Empty;
TextBox pTextBox = new TextBox();
pTextBox.ID = "ID_TextBox";
pTextBox.Text = "Some text";
pNodeChildTextBox.PostRenderControls.Add(pTextBox);
pNodeParent.ChildNodes.Add(pNodeChildTextBox);
this.treeViewContainer.Controls.Add(m_pTreeView);
}*/
//load XML file and use it to make the tree view
public void renderEditTree()
{
m_pTreeView = new ContainerTreeView();
XDocument document = XDocument.Load(Server.MapPath("~/Releases_files/releases.xml"));
foreach (XElement element in document.Descendants("Release"))
{
XName name0 = "version";
XAttribute a0 = element.Attribute(name0);
string temp0 = a0.Value;
ContainerTreeNode pmTextBox = m_pTreeView.CreateTreeNode();
pmTextBox.Value = "ParentTextBox";
pmTextBox.Text = String.Empty;
TextBox pTextBox = new TextBox();
pTextBox.ID = temp0;
pTextBox.Text = temp0;
pmTextBox.PostRenderControls.Add(pTextBox);
m_pTreeView.Nodes.Add(pmTextBox);
//n0.Text = temp0;
//TreeView1.Nodes.Add(n0);
foreach (XElement myElement in element.Descendants("Feature"))
{
XName name = "Name";
XAttribute a = myElement.Attribute(name);
string temp = a.Value;
ContainerTreeNode pcTextBox = m_pTreeView.CreateTreeNode();
pcTextBox.Value = "ChildTextBox";
pcTextBox.Text = String.Empty;
TextBox p2TextBox = new TextBox();
p2TextBox.ID = temp;
p2TextBox.Text = temp;
pcTextBox.PostRenderControls.Add(p2TextBox);
pmTextBox.ChildNodes.Add(pcTextBox);
}
this.treeViewContainer.Controls.Add(m_pTreeView);
}
}
#endregion
#region simpleTreeView
//old code
//load XML file and use it to make the tree view
public void makeTree()
{
TreeView1.Nodes.Clear();
XDocument document = XDocument.Load(Server.MapPath("~/Releases_files/releases.xml"));
foreach (XElement element in document.Descendants("Release"))
{
TreeNode n0 = new TreeNode();
XName name0 = "version";
XAttribute a0 = element.Attribute(name0);
string temp0 = a0.Value;
n0.Text = temp0;
TreeView1.Nodes.Add(n0);
foreach (XElement myElement in element.Descendants("Feature"))
{
TreeNode n = new TreeNode();
XName name = "Name";
XAttribute a = myElement.Attribute(name);
string temp = a.Value;
n.Text = temp;
n0.ChildNodes.Add(n);
}
}
}
//action to do when selected node is changed
protected void TreeView1_SelectedNodeChanged(object sender, EventArgs e)
{
XDocument document = XDocument.Load(Server.MapPath("~/Releases_files/releases.xml"));
//debug
//Label1.Text = TreeView1.SelectedNode.Text;
//Label5.Text = Convert.ToString(TreeView1.SelectedNode.Depth);
//case1: feature selected
if (TreeView1.SelectedNode.Depth > 0)
{
string featureName = TreeView1.SelectedNode.Text;
string releaseName = TreeView1.SelectedNode.Parent.Text;
foreach (XElement element in document.Descendants("Release"))
{
//find the right release in XML
XName name = "version";
XAttribute a = element.Attribute(name);
string versionAttribute = a.Value;
if (releaseName.Equals(versionAttribute))
{
foreach (XElement myElement in element.Descendants("Feature"))
{
//find the right feature in XML
XName name1 = "Name";
XAttribute a1 = myElement.Attribute(name1);
string versionAttribute1 = a1.Value;
if (featureName.Equals(versionAttribute1))
{
//found the right node, now populate the Fields
IEnumerable<XElement> dates = element.Descendants("Date");
XElement date = dates.First<XElement>();
Label5.Text = date.Value;
IEnumerable<XElement> statuses = element.Descendants("Status");
XElement status = statuses.First<XElement>();
Label6.Text = status.Value;
IEnumerable<XElement> types = myElement.Descendants("Type");
XElement type = types.First<XElement>();
Label7.Text = type.Value;
IEnumerable<XElement> developers = myElement.Descendants("Developer");
XElement developer = developers.First<XElement>();
Label8.Text = developer.Value;
IEnumerable<XElement> details = myElement.Descendants("Detail");
XElement detail = details.First<XElement>();
tb.Text = detail.Value;
}
}
}
}
}
//case2: Release selected
else
{
string releaseName = TreeView1.SelectedNode.Text;
foreach (XElement element in document.Descendants("Release"))
{
//find the right release in XML
XName name = "version";
XAttribute a = element.Attribute(name);
string versionAttribute = a.Value;
if (releaseName.Equals(versionAttribute))
{
//found the right node, now populate the Fields
IEnumerable<XElement> dates = element.Descendants("Date");
XElement date = dates.First<XElement>();
Label5.Text = date.Value;
IEnumerable<XElement> statuses = element.Descendants("Status");
XElement status = statuses.First<XElement>();
Label7.Text = " ";
Label8.Text = " ";
tb.Text = " ";
}
}
}
}
#endregion
#region userInputs
protected void Button2_Click(object sender, EventArgs e)
{
}
//edit tree check box
protected void CheckBox1_CheckedChanged(object sender, EventArgs e)
{
if (CheckBox1.Checked )//&& TreeView1.Visible==true)
{
TreeView1.Visible = false;
if (m_pTreeView != null)
{
m_pTreeView.Visible = true;
}
Label5.Enabled = false;
Label6.Enabled = false;
Label7.Enabled = false;
Label8.Enabled = false;
tb.Enabled = false;
}
else
{
TreeView1.Visible = true;
if (m_pTreeView != null)
{
m_pTreeView.Visible = false;
}
Label5.Enabled = true;
Label6.Enabled = true;
Label7.Enabled = true;
Label8.Enabled = true;
tb.Enabled = true;
}
}
#endregion
}
}
I may be misunderstanding the code a bit, but if the PreRenderContainer and PostRenderContainer properties implement INamingcontainer and you change their IDs, I think you might not be letting them do their job. It should automatically give you unique ids. Like ctl00, ctl01 etc...
You need to set the ID property of the control to some unique value before adding it to the page. There are a number of tricks you can use to make this work out. If you provide more code, we can provide some ideas for solutions tailored to your situation.
Edit
It looks like you've got some pretty complicated stuff going on here, so I'm not grokking it fully. However, I'd look at setting the IDs of your ContainerTreeNodes when they're instantiated, rather than during the OnInit phase. I'd also make the ContainerTreeNode architecture support a means of traversing and removing a node within itself, rather than trying to manually remove a node based on a Control ID from outside the tree.