Cannot find instance of dynamically added UserControl .Net - c#

I have a UserControl which I am loading into a div which is inside an UpdatePanel. Here is my code for loading it:
controls.IDLControl IdlControl = LoadControl(#"~/controls/IDLControl.ascx") as controls.IDLControl;
IdlControl.ClientIDMode = ClientIDMode.Static;
IdlControl.ID = "IDLControl";
spGroup.Controls.Clear();
spGroup.Controls.Add(IdlControl);
And here is my code for trying to retrieve an instance of it:
controls.IDLControl IdlControl = RecursiveFindControl(this, "IDLControl") as controls.IDLControl;
private Control RecursiveFindControl(Control targetControl, string findControlId) {
if (targetControl.HasControls()) {
foreach (Control childControl in targetControl.Controls) {
if (childControl.ID == findControlId) {
return childControl;
}
RecursiveFindControl(childControl, findControlId);
}
}
return null;
}
But, all I get is null. I need help on figuring this out.
AFAIK, I need to re-add the control to the page on pre-init but it is one of the controls that can be added depending on which option is selected from a drop down list (which also is filled dynamically). I am stuck trying to figure out how to make this work.

You can try something like this to add your control back in the Page_Init based on the option selected in your DropDownList.
protected void Page_Init(Object sender, EventArgs e)
{
if (IsPostBack)
{
if (drpYourDropDown.Items.Count > 0 && drpYourDropDown.SelectedItem.Text == "yourOption")
{
AddIDLControl();
}
}
}
private void AddIDLControl()
{
controls.IDLControl IdlControl = LoadControl(#"~/controls/IDLControl.ascx") as controls.IDLControl;
IdlControl.ClientIDMode = ClientIDMode.Static;
IdlControl.ID = "IDLControl";
spGroup.Controls.Clear();
spGroup.Controls.Add(IdlControl);
}

Related

Update Control on User Control from Main Form

Background
I have a main form that has a tableLayoutPanel. Within that I have three panel, a header, footer and left side bar. In the remaining space I add and remove usercontrols this one in the example is called ctrlmanagepreset.
Within these usercontrols I have controls. Namely a Listsbox s, that i'm trying to add items too.
I am getting the items from an xml file that does contain items and reading them in to an object list. The name of each object is then added to the listbox.
All of the Controls are accessable as I've made them public. I think it might be due to the way i create and add them?
Question
Why aren't the Listboxes updating, showing the added items?
Code
Button click event that creates usercontrol
public void btnManage_Click(object sender, EventArgs e)
{
tableLayoutPanel.Controls.Add(new ctrlManagePresets () { Dock = DockStyle.Left }, 1, 1);
PopulateCreateJob();
}
Method that Populates Listbox
public void PopulateCreateJob()
{
ctrlManagePresets ctrlmanagepresets = new ctrlManagePresets();
//read in contents of xml file
if (File.Exists(JoblistXmlFilepath))
{
XmlSerializer deserializer = new XmlSerializer(typeof (List<Favourite>));
TextReader reader = new StreamReader(JoblistXmlFilepath);
//create list of old fave objects
var xmlList = (List<Favourite>) deserializer.Deserialize(reader);
reader.Close();
if (xmlList.Count > 0)
{
foreach (Favourite t in xmlList)
{
//add favourite objects to combobox
try
{
ctrlmanagepresets.lbCreateJob.Items.Add(t.Name);
}
catch
{
MessageBox.Show(#"There is an object with no name in the XML.", #"Message",
MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
}
}
ctrlmanagepresets.lbCreateJob.Refresh();
}
else
{
ctrlmanagepresets.lbCreateJob.Items.Add(#"Settings File Not Found");
ctrlmanagepresets.lbCreateJob.Enabled = false;
ctrlmanagepresets.lbCreateJob.BackColor = Color.DarkRed;
}
}
You are not adding the items to the instance of the control that you add to your tableLayoutPanel.
Just make your PopulateCreateJob return the instance that is built and intialized with the xml data
public void btnManage_Click(object sender, EventArgs e)
{
ctrlManagePresets ctrl = PopulateCreateJob();
ctrl.Dock = DockStyle.Left;
tableLayoutPanel.Controls.Add(ctrl, 1, 1);
}
public ctrlManagePresets PopulateCreateJob()
{
ctrlManagePresets ctrlmanagepresets = new ctrlManagePresets();
// current code that initialize the instance of your control
....
// return the control instance initialized to the caller
return ctrlmanagepresets;
}

C# ListView from Another Function

Please forgive me for such a stupid question. I am sure many of you will find this easy, where I have sent almost half the day reading trying to figure this out.
Here is the problem:
I have a FORM (Form1.cs) made. In that form I created a listview, and named it "ListView1".
Within the Form1.cs, I call a function called FileManager(this), where I pass in the THIS object.
In FileManager.cs I was able to listviewArray= originalForm.Controls.Find("listView1", true) and find that 'listview'.
When I do a listviewArray[0]<-- I can't seem to add a list to it.
FileManager.cs
FileManager(object sender)
{
if (sender != null)
{
originalForm = (Form)sender;
}
}
public void getFiles()
{
filePaths = Directory.GetFiles(hsocDir);
if(filePaths != null)
{
listviewArray= originalForm.Controls.Find("listView1", true);
if(listviewArray != null)
{
ListViewItem lvi = new ListViewItem("text");
// My Array is listViewArray
// How to add things to Lvi to it.
}
}
== Form1.cs
public Form1()
{
InitializeComponent(`enter code here`);
mysql = new MySQLCheck(this);
fileManager = new FileManager(this);
fileManager.getFiles();
}
You can't access element 0 of the collection because the collection is empty. To add an item, use:
listViewArray.Items.Add(lvi);
You need to modify the Items collection instead of the ListView itself for this to work, as ListView is not a collection (its a control).
listViewArray.Items.Add(lvi);
Also in your listview,setting this properties will help :
// Set the view to show details.
listViewArray.View = View.Details;
// Select the item and subitems when selection is made.
listViewArray.FullRowSelect = true;
// Display grid lines.
listViewArray.GridLines = true;

How To Set Many Elements Visible Property at one time in ASP.NET

Suppose I have 5 Elements => Element1, Element2, Element3, Element4, Element5.
General Way to set their Visible Property is:
Element1.Visible = false;
Element2.Visible = false;
Element3.Visible = false;
Element4.Visible = false;
Element5.Visible = false;
Or Another Way is
Element1.Visible = Element2.Visible = Element3.Visible = Element4.Visible = Element5.Visible = false;
Now My Question is:
Is It possible to set all elements property Visible at same time without writing Visible against every element name. In Simple Word only need to write Visible one time.
You can find controls and set its visisble property
Here is the example code
protected void Page_Load(object sender, EventArgs e)
{
HideRadioButtonLists(Page.Controls);
}
private void HideRadioButtonLists(ControlCollection controls)
{
foreach (WebControl control in controls.OfType<WebControl>())
{
if (control is RadioButtonList)
control.Visible = false;
else if (control.HasControls())
HideRadioButtonLists(control.Controls);
}
}
See if it helps you.

Listbox clears all items during datasource change

When I change the datasource of my Listbox all items are cleared, when loading new data into this Listbox it stays clear.
I have another ListBox right new to this one with the same refresh code but that one refreshes perfectly.
private void RefreshContacts()
{
this.ListContacts.DataSource = null;
this.ListContacts.DataSource = this.contacts;
this.BoxCountContacts.Text = this.ListContacts.Items.Count.ToString();
}
Anyone have an idea how to fix the listbox from being cleared and bugged?
Here is the full refresh codes of the two listboxes
private Contact[] contacts, feed; private Boolean isFeed;
internal ArcFeed()
{
this.InitializeComponent();
this.contacts = this.feed = new Contact[0];
}
private void RefreshForm(Boolean isFeed)
{
if (isFeed)
{
this.RefreshFeed();
}
else
{
this.RefreshContacts();
}
}
private void RefreshContacts()
{
this.ListContacts.DataSource = null;
this.ListContacts.DataSource = this.contacts;
this.BoxCountContacts.Text = this.ListContacts.Items.Count.ToString();
}
private void RefreshFeed()
{
this.ListFeed.DataSource = null;
this.ListFeed.DataSource = this.feed;
this.BoxCountFeed.Text = this.ListFeed.Items.Count.ToString();
}
private void OpenFile()
{
if (this.isFeed)
{
this.BoxFileFeed.Text = this.DialogOpen.FileName;
this.feed = ArcBuzz.Load(this.DialogOpen.FileName);
}
else
{
this.BoxFileContacts.Text = this.DialogOpen.FileName;
this.contacts = ArcBuzz.Load(this.DialogOpen.FileName);
}
this.RefreshForm(this.isFeed);
}
All code is debugged and follows it's course properly, I don't see any errors, the correct listbox's datasource are set and changed.
Just to make sure, have you checked that there are actually items in the contacts collection?
Also, if you've got two Listboxes, double check that you are using the right Listbox in each of the refresh code sections.
Sounds stupid, but its silly mistakes like this that get overlooked a lot of the time. With databinding its usually something small like this stopping it working.

Using Build Manager Class to Load ASPX Files and Populate its Controls

I am using BuildManager Class to Load a dynamically generated ASPX File, please note that it does not have a corresponding .cs file.
Using Following code I am able to load the aspx file, I am even able to loop through the control collection of the dynamically created aspx file, but when I am assigning values to controls they are not showing it up. for example if I am binding the value "Dummy" to TextBox control of the aspx page, the textbox remains empty.
Here's the code that I am using
protected void Page_Load(object sender, EventArgs e)
{
LoadPage("~/Demo.aspx");
}
public static void LoadPage(string pagePath)
{
// get the compiled type of referenced path
Type type = BuildManager.GetCompiledType(pagePath);
// if type is null, could not determine page type
if (type == null)
throw new ApplicationException("Page " + pagePath + " not found");
// cast page object (could also cast an interface instance as well)
// in this example, ASP220Page is a custom base page
System.Web.UI.Page pageView = (System.Web.UI.Page)Activator.CreateInstance(type);
// call page title
pageView.Title = "Dynamically loaded page...";
// call custom property of ASP220Page
//pageView.InternalControls.Add(
// new LiteralControl("Served dynamically..."));
// process the request with updated object
((IHttpHandler)pageView).ProcessRequest(HttpContext.Current);
LoadDataInDynamicPage(pageView);
}
private static void LoadDataInDynamicPage(Page prvPage)
{
foreach (Control ctrl in prvPage.Controls)
{
//Find Form Control
if (ctrl.ID != null)
{
if (ctrl.ID.Equals("form1"))
{
AllFormsClass cls = new AllFormsClass();
DataSet ds = cls.GetConditionalData("1");
foreach (Control ctr in ctrl.Controls)
{
if (ctr is TextBox)
{
if (ctr.ID.Contains("_M"))
{
TextBox drpControl = (TextBox)ctr;
drpControl.Text = ds.Tables[0].Rows[0][ctr.ID].ToString();
}
else if (ctr.ID.Contains("_O"))
{
TextBox drpControl = (TextBox)ctr;
drpControl.Text = ds.Tables[1].Rows[0][ctr.ID].ToString();
}
}
}
}
}
}
}
I saw that you got part of your code from How To Dynamically Load A Page For Processing. Read the comments too as this one by Mike.
Invert this:
((IHttpHandler)pageView).ProcessRequest(HttpContext.Current);
LoadDataInDynamicPage(pageView);
To this:
LoadDataInDynamicPage(pageView);
((IHttpHandler)pageView).ProcessRequest(HttpContext.Current);
In this case changing the order of the calls does change the end result I think. The inverse of Commutativity property. :)

Categories

Resources