pass parameters to control - c#

I am working on an ASP .net project. I am trying to load a user control in a Control object with the following code and i am trying to pass a parameter to that control. On the debugging mode I get an error on that line saying that The file '/mainScreen.ascx?matchID=2' does not exist.. If I remove the parameters then it works ok. Can anyone help me to pass those parameters? Any suggestions?
Control CurrentControl = Page.LoadControl("mainScreen.ascx?matchID=2");

You cannot pass the parameter via query-string notation because user controls are simply "a building blocks" referenced by virtual path.
What you can do instead is to make a public property and assign the value to it once the control is loaded:
public class mainScreen: UserControl
{
public int matchID { get; set; }
}
// ...
mainScreen CurrentControl = (mainScreen)Page.LoadControl("mainScreen.ascx");
CurrentControl.matchID = 2;
You can now use the matchID inside your user control like the following:
private void Page_Load(object sender, EventArgs e)
{
int id = this.matchID;
// Load control data
}
Note that the the control is participating in the page life cycle only if it's added into the page tree:
Page.Controls.Add(CurrentControl); // Now the "Page_Load" method will be called
Hope this helps.

Related

C# I'm trying to create a web user control with custom classes, and I am getting a Object not set to an instance of an Object Error

I hope you can help me with this. I am creating an internal webforms asp.net site to display a list of internally used documents in different categories.
I decided to create a custom document class to put in a list to hold the documents, and then a custom web user control to display the documents wherever they want them on the site.
The documents class is in a general class file in my App_Code folder.
cabinet.cs
public class Document
{
private string _Url;
private string _Title;
public Document(string URL, string Title)
{
_Url = URL;
_Title = Title;
}
public string URL
{
get { return _Url; }
set { _Url = value; }
}
public string Title
{
get { return _Title; }
set { _Title = value; }
}
}
This code works just fine. Then in my user control I create a list of type document and initiate it in Page_Load(). Then I created a public method to add new documents to the list.
DocDisplay.ascx.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class DocDisplay : System.Web.UI.UserControl
{
private List<Document> _DocList;
protected void Page_Load(object sender, EventArgs e)
{
_DocList = new List<Document>();
}
public void Add(string URL, string Title)
{
_DocList.Add(new Document(URL, Title));
}
public void WriteDocuments()
{
foreach (Document doc in _DocList)
{
Response.Write($"<span class='document'><a href='{doc.URL}'>{doc.Title}</a></span>");
}
}
}
I am getting the error in the add method. It says that my object is not to an instance of an object. But I do that in Page_Load.
index.aspx.cs
protected void Page_Load(object sender, EventArgs e)
{
pageDocs.Add("index.aspx", "Hello World!");
pageDocs.Add("index.aspx", "Red Rum");
pageDocs.Add("index.aspx", "Lorum Ipsum");
}
I have registered my user control in my index page.
<%# Register Src="~/DocDisplay.ascx" TagPrefix="uc" TagName="DocDisplay" %>
<uc:DocDisplay ID="pageDocs" runat="server" />
So I am not exactly sure why I am getting that error. As far as I can tell, there is nothing wrong with my code. If you could help I would greatly appreciate it.
Events get fired starting from the root of control hierarchy and end at the leaf nodes. Index.Page_Load is being called before DocDisplay.Page_Load has an opportunity to instantiate the list.
The _DocList field needs a value before it can be used by anything, so initialization needs to happen as early as possible. This is accomplished very easily with a field initializer. Declare and assign it all at once:
private List<Document> _DocList = new List<Document>();
When the Index class instantiates its child controls early in the page life cycle, _DocList will immediately have an object reference.
It's tempting to say, "Page_Init will be called sooner; I'll do it there." This may work at first, but if you do any dynamic control loading, you'll soon find out that it's a balancing act. A dynamically loaded control has to play event catch-up, so its Init event can be fired after statically loaded controls have started firing Load events. It's important to use each event for its purpose, and not for its timing, and use constructors (and field initializers) to initialize non-control class state.

Save/Open Dynamically Created Controls In a Form

I am trying to develop a program in which it could create forms and add controls to it at runtime.
It also should be able to save, (Open and Edit) the forms created with the new controls added it at Runtime.The Application starts In the Main form.
CODE BEHIND MAIN Form
private void Btn_CREATE_FORM_Click(object sender, EventArgs e)
{
Form_Properties fp = new Form_Properties();
fp.Show();
}
private void BTn_ADD_BTN_Click(object sender, EventArgs e)
{
/// WHAT CODE SHOULD I ENTER TO ADD BUTON TO NEW FORM
}
Basically the main form is used to create/open/save new forms and add controls to it.
When the user clicks on Create New Form button the user will be presented with the following form (FORM_PROPERTIES) in which the user can customize the name, width and height of the new form.
CODE BEHIND FORM_PROPERTIES Form
public partial class Form_Properties : Form
{
public Form_Properties()
{
InitializeComponent();
}
String form_name;
int form_width;
int form_height;
private void Btn_OK_Click(object sender, EventArgs e)
{
form_name = TBox_NAME.Text;
form_width = Convert.ToInt32(TBox_WIDTH.Text);
form_height = Convert.ToInt32(TBox_HEIGHT.Text);
New_Form nf = new New_Form();
nf.Text = form_name;
nf.Width = form_width;
nf.Height = form_height;
nf.Show();
}
}
The following image shows what happens at runtime based on the code I have written so far.
ISSUES
Need help to Write Code
To add controls to new form created.
To Save/Open/Edit Functionalities.
I also need to know the method to access properties of added controls at runtime.
eg: If the user adds a text box to the NEW FORM and decides to type some text in it, I need a method to save that text.
Is there a way for me to name the added controls?
It seems you want to build some kind of WinForms' form designer. Your program would be similar to Glade (though Glade is much more powerful).
I'm afraid the question is too broad, though. There are many questions to answer, for example, how do you describe the created interface.
While Glade uses XML, you can choose another format, such as JSON. Let's say that you have a TextBox with the word "example" inside it.
{ type:"textbox" text:"example" }
It seems you want to add your components to the form as in a stack. Maybe you could add its position. For example, a form containing a label
("data"), a textbox ("example"), and a button ("ok"), would be:
{
{ pos:0, type:"label", text:"data" },
{ pos:1, type:"textbox", text:"example" },
{ pos:2, type:"button", text:"ok" },
}
But this is just a representation. You need to a) store this when the form is saved, and b) load it back when the form is loaded.
For that, you will need a class representing the components, such as:
public class Component {
public override string ToString()
{
return string.Format( "position:{0}, text:{1}", this.Position, this.Text );
}
public int Position { get; set; }
public string Text { get; set; }
}
public class TextBoxComponent: Component {
public override string ToString()
{
return base.ToString() + "type:\"textbox\"";
}
}
...and so on. This is a big task, I'm afraid, with no simple answer.

How to persist design time property changes that were made programmatically?

I have a custom control that I added an Id string property to.
When the control is placed on a form, I want the constructor to set this to Guid.NewGuid().ToString(), but only if it hasn't been set before.
When I manually edit this property from the designer, it adds a line of code to the Designer.cs file. How can I do that programmatically?
Specifically, how to do it from within the custom control?
I have created sample usercontrol that fits your requrements. In this case is "MyLabel" that inherits from Label.
First create separate library that holds MyLabel class and here is the code for this class:
public class MyLabel: Label
{
public string ID { get; set; }
protected override void OnCreateControl()
{
base.OnCreateControl();
if (this.DesignMode && string.IsNullOrEmpty(this.ID))
{
this.ID = Guid.NewGuid().ToString();
}
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
this.Text = this.ID;
}
}
As you see my control has ID property that is populated if control is in design mode and no value has been set yet. Checking design mode is important so value will not change if you reopen the project.
Override for OnPaint event is there just to see actual ID value in real time it's not required.
I believe what you need is Properties.Settings. See MSDN page.
You can set these to default values during design, or load and save at runtime.
Example: with the designer, create a new user scoped string[] named IDs. Then in your constructor, something like this
string ID = "";
if (Properties.Settings.Default.IDs!=null && Properties.Settings.Default.IDs.Length>0) {
ID = Properties.Settings.Default.IDs[0];
}
else {
ID = "random";
Properties.Settings.Default.IDs = new string[1];
Properties.Settings.Default.IDs[0] = ID;
Properties.Settings.Default.Save();
}
This will use the first element of the stored array if there is one, or it will create a new string if there isn't, and persist it (so it will be read from the settings next time you run the program).

.net ASCX help with passining info & Hiding Div

Alright, I am trying to accomplish this: When a user clicks a button that is on a ascx web user control with text boses, it first displays a DIV that is hidden, this div contains a ascx web user control. Basically I want that web user control to grab what they typed in the boxes on the first web user control, and then apply to a SQL search from what the users type in the text boxes on the first page. Is this possible or do I need to rethink my strategy on this? I am programming in c# for the SQL statements.
It is possible.
You can define properties of the control which accepts the text input, and expose the values using direct field access, variables, or session variables; you can then use FindControl from within the newly displayed control, and, if found, utilise the now exposed properties to gather the values required.
For instance, your input control code-behind might look something like this:
partial class MyControl : UserControl
{
public string MyFieldValue
{
get { return MyFieldTextBox.Text; }
}
}
And in the next control, to use it, a little like this:
partial class MyControl : UserControl
{
protected void Page_Load(object sender, EventArgs e)
{
var myControl = Page.FindControl("MyControlInstanceName") as MyControl;
if (myControl != null)
{
var myFieldValue = myControl.MyFieldValue;
}
}
}
Is the 2nd user control embedded in the 1st or not?
If not, you can make anything available upwards between user controls by simply adding public properties to your user controls. This means they can then be accessed from the page level or the containing user control. For example, if I have UCA, UCB, UCC
UCA contains UCB and UCC is hidden.
UCB has the following property
public string UserEnteredName
{
get { return NameTextBox.Text; }
}
UCC has the following property and method
public string UserEnteredName { get; set; }
public BindResults()
{
UserEnteredLiteral.Text = UserEnteredName;
}
Then tie it together with UCA:
protected MyButton_Click(object sender, EventArgs e)
{
UCC.UserEnteredName = UCB.UserEnteredName;
... some logic herre.
UCC.BindResults();
}
You can also raise an event from UCB that can be responded to in UCA if your button or submit action exists in UCB.

Passing User Control Class to Host Page

How can I pass user control properties to the page AND make these properties available to all methods on the page (and not just to one method that is fired on a control action, e.g. onControlClick)
I have a set up of essentially 3 pages:
user control (ascx/cs)
class (cs) - that contains user control properties
host page (aspx/cs) - references the user control
The user control consists of 3 interrelated dropdowns. I'm having success passing these dropdown values through a class onto the page via an event that is fired when a user clicks on the dropdown menu. So this way the host page is continously aware of the values in the user control. However, I want the page to use the control's properties (stored in a class) on all of its methods - how do I make this user control class available to all?
Also I'm using ASP.NET and C# by the way.
Here's the Code (not sharing the full code here - just the snippets of a similar code block)
On the ASPX for Menu Host Page:
<linked:LinkMenu2 id="Menu1" runat="server" OnLinkClicked="LinkClicked" />
Host Page (cs):
protected void dropdownclicked(object sender, ddtestEventArgs e)
{
if (e.Url == "Menu2Host.aspx?product=Furniture")
{
lblClick.Text = "This link is not allowed.";
e.Cancel = true;
}
else
{
// Allow the redirect, and don't make any changes to the URL.
}
}
Host Page (aspx)
<asp:dropdowncustom ID="dddone" runat="server" OnddAppClicked="dropdownclicked" />
Control (cs)
public partial class usercontrol_tests_dropdown1 : System.Web.UI.UserControl
{
public event ddtestEventHandler ddAppClicked;
}
public void selectapp_SelectedIndexChanged(object sender, EventArgs e)
{
ddtestEventArgs args = new ddtestEventArgs(selectlink.SelectedValue);
ddAppClicked(this, args);
}
Class:
public class ddtestEventArgs : EventArgs
{
// Link
private string link;
public string Link
{
get { return link; }
set { link = value; }
}
public ddtestEventArgs(string link)
{
Link = link;
}
}
public delegate void ddtestEventHandler(object sender, ddtestEventArgs e);
Hopefully this is what you're after. The best way to do it is to expose your controls as public properties from your user control. So, in your user control, for each drop down list add a property:
public DropDownList DropDown1
{
get { return dropDownList1; }
}
public DropDownList DropDown2
{
get { return dropDownList2; }
}
You can do the same for any other properties you want to access on the host page:
public string DropDown1SelectedValue
{
get { return dropDownList1.SelectedValue; }
set { dropDownList1.SelectedValue = value; }
}
Then, from your host page you can access the properties through the user control:
string value = UserControl1.DropDown1SelectedValue;
or
string value = UserControl1.DropDownList1.SelectedValue;
Here's a couple of other answered questions that you might find useful as I think (if I've understood correctly) this is what you're doing:
Getting data from child controls loaded programmatically
How to change the value of a control in a MasterPage.

Categories

Resources