I am using two user controls in my web application. I want to read a Label text from a user control via another user control. How can i read it?
You should refactor your code and not rely to content of some label on another UI control. Get that value the same way as you do in that User Control, or extract that functionality in another class to avoid code duplication, and call it from both places.
But, if you wont to stick with this existing code you should create Interface and capture all UserControls functionality that you wont to called from outside code (in your case : return label text). Then implement that interface in User Controls that must be called from outside, after that is all about finding control instances, you can do that by enumerating all Page child controls. Here is the example code of simple interface that defines that control must return some Label text, and a class that finds user control by name in control tree :
public interface IUserControl
{
string LabelText();
}
public class PageUserControls
{
private Page parentPage;
public PageUserControls(Page myParentPage)
{
this.parentPage = myParentPage;
}
private IEnumerable<Control> EnumerateControlsRecursive(Control parent)
{
foreach (Control child in parent.Controls)
{
yield return child;
foreach (Control descendant in EnumerateControlsRecursive(child))
yield return descendant;
}
}
public IUserControl GetControl(string controlName)
{
foreach (Control cnt in EnumerateControlsRecursive(this.parentPage))
{
if (cnt is IUserControl && (cnt as UserControl).AppRelativeVirtualPath.Contains(controlName))
return cnt as IUserControl;
}
return null;
}
}
then you have to implement that interface in user control that holds that Label :
public partial class WebUserControl1 : System.Web.UI.UserControl, IUserControl
{
public string LabelText()
{
return Label1.Text;
}
}
And finally use it from another User control :
PageUserControls puc = new PageUserControls(this.Page);
string txt1 = puc.GetControl("WebUserControl1.ascx").LabelText();
btw. method EnumerateControlsRecursive is adopted from SO answer to Finding all controls in an ASP.NET Panel?
use like this...
create one public property in the user control and call that property using user controls name where you want that value....
Take a look at this article on MSDN.
In a short, you can access other controls if you know the ID.
Related
I have created a custom checkbox template field by deriving it from System.Web.UI.WebControls.TemplateField. The template for this field has been created by creating a class which implements ITemplate interface. When any postback happens on the page the values in the checkboxes is lost.
To get this working temporarily I have used viewstate to store the state of checkboxes in the checkbox column, but going further I want to completely avoid this as I will be using more template fields in same fashion in my application.
Please let me know if I am missing anything.
Following is the code:
namespace MyControls
{
public class CheckBoxTemplateField : TemplateField
{
public CheckBoxTemplateField()
{
this.HeaderTemplate = new CheckBoxTemplate();
this.ItemTemplate = new CheckBoxTemplate();
}
}
public class CheckBoxTemplate : ITemplate
{
public void InstantiateIn(Control container)
{
CheckBox chk = new CheckBox();
container.Controls.Add(chk);
}
}
}
Regards,
Gaurav
checkbox is known with their problem maintaining their value in postback
1 solution is to store its value in hidden fiesld and to read it in server.
p.s. thhis has nothing to do with viewstate.input control doesnt saves their value in viewstate ( excpet textbox which has the 'ontextchange' event)
I want to extend DropDownList control to include an option for creating or editing the options. For example; for a list of projects in the dropdown list, there will be another option that says "Create new project..." or "Edit projects..." and this will be the last option in the list. When user selects this option, the selectedIndex or selectedItem will not change and corresponding action will be taken (for example a popup window shows up). This will be a convenient way for the end user.
Now I want this to work independent of the context and the class must be reusable. User will only specify the optionText and optionFunction to work this out. The basic structure of the class looks like this:
public class OptiveDropDownList extends DropDownList
{
private var _enableOption:Boolean;
private var _optionText:String;
private var _originalDataProvider:IList;
[Bindable] public var optionFunction:Function;
public function OptiveDropDownList()
{
super();
}
public function set optionText(value:String):void
{
_optionText = value;
dataProvider = _originalDataProvider;
}
public function set enableOption(value:Boolean):void
{
_enableOption = value;
dataProvider = _originalDataProvider;
}
public override function set dataProvider(value:IList):void
{
_originalDataProvider = value;
var dp:IList = null;
if(!value){
dp=new ArrayCollection(value.toArray());
if(_enableOption){
var opt:Object=new Object();
opt[labelField]=_optionText;
dp.addItem(opt);
}
}
super.dataProvider = dp;
}
[Bindable]
public override function get dataProvider():IList
{
return _originalDataProvider;
}
}
I hope my code is clear to understand, I am adding an extra object to the dataprovider for the option. Field names are self-explanatory.
Now my question is how to know whether the dataprovider's items have changed? Which functions should I override and how to do it. I have tried using a ChangeWatcher to watch the length property of the dataprovider, but it doesnt work if only an object in the dataprovider has changed. I need to capture these changes and update the view.
I also need to capture the selection and call optionFunction, preventing the default action not to give index out of bounds error.
Thanks in advance.
Just add an event listener to the original dataProvider. All implementations of IList should dispatch CollectionEvent.COLLECTION_CHANGE when the the list changes (e.g. add, remove or when an existing object in the list has been changed). In your event handler you can update the DropDownList's dataProvider accordingly.
By overriding the mx_internal method setSelectedIndex() you can adjust the selection according to your wishes. Take a look at the blog post "Disable selection on some items in a spark List" for some inspiration.
I'm trying to add some user controls on a page. Thats easy, I just do it like this.
UserControl block = (categoryblock) LoadControl("categoryblock.ascx");
Panel1.Controls.Add(block);
But i want to access the label controls and more that are inside the categoryblock.ascx.
How would i do that ?
I cant do it like this,
block.l_itemName.text = "blabla";
I managed to user FindControl("l_itemName") but i would rather like to have the intellisense.
create following property in your user control:
public string ItemName() {
get() {
return l_itemName.text;
}
set(String value) {
l_itemName.text = value;
}
}
This will make you able to do block.ItemName = ""or string temp = block.ItemName
I hope this will help
Im trying to create a "user control menu" where links to a page's usercontrols are placed at the top of the page. This will allow me to put several usercontrols on a page and allow the user to jump to that section of the page without scrolling so much. In order to do this, I put each usercontrol in a folder (usercontrols) and gave each control a Description property (<%# Control Language="C#" Description = "Vehicles" .... %>).
My question is how can I access this description dynamically? I want to use this description as the link in my menu. So far, I have a foreach on my page that looks in the ControlCollection for a control that is of the ASP.usercontrols type. If it is I would assume that I could access its attributes and grab that description property. How can I do this? (Im also open to a better way to achieve my "user control menu", but maybe thats another question.) Should I use ((System.Web.UI.UserControl)mydynamiccontrol).Attributes.Keys?
you can iterate over the collection and do either a switch or a few if statements
I would suggst you have an interface or an abstract base class for all your user controls:
public abstract class MyBaseClass : UserControl
{
public abstract string MyDescription {get;}
}
public MyUserControlA : MyBaseClass
{
public string MyDescription {get {return "my description";}}
}
public MyUserControlB : MyBaseClass
{
public string MyDescription {get {return "my other description";}}
}
Then you can loop over them as you do:
foreach ...
if (mydynamiccontrol is MyBaseClass)
{
Response.Write(((MyBaseClass)mydynamiccontrol).MyDescription);
}
Hope this helps
If I create a user control (EDIT:not a web control/server control) it's pretty trivial to get databinding. I just add a datasourceID property.
In code behind (vb)
Partial Public Class BandedControl
Inherits UserControl
Public Property DataSourceID() As String
Get
Return MyGridView.DataSourceID
End Get
Set(ByVal value As String)
MyGridView.DataSourceID = value
End Set
End Property
End Class
In code behind (c#)
public partial class BandedControl : UserControl
{
public string DataSourceID {
get { return MyGridView.DataSourceID; }
set { MyGridView.DataSourceID = value; }
}
}
My issue is that this breaks design time rendering and also I don't get a drop down list to choose my datasource. How do I resolve this. (Hint: I think I need a type convertor, but all the info I can find relates to server controls not user controls).
You could try adding the IDReferenceProperty attribute to your property definition...
public partial class BandedControl : UserControl
{
[System.Web.UI.IDReferenceProperty(typeof(DataSourceControl))]
public string DataSourceID
{
get
{
return MyGridView.DataSourceID;
}
set
{
MyGridView.DataSourceID = value;
}
}
}
See http://msdn.microsoft.com/en-us/library/system.web.ui.idreferencepropertyattribute.aspx for more info about the IDReferencePropertyAttribute class.
If that doesn't work - I'd also try to inherit from DataBoundControl instead of UserControl and see if that gets you anywhere.
Web UserControls are compiled dynamically at run time and so are not rendered at Design time, what you want to do is create a Web Custom Control. Your best bet here is to extend one of the existing Bindable Web Controls
http://msdn.microsoft.com/en-us/library/aa651710(VS.71).aspx
Not sure if this is exactly what you want but I seem to remember them showing something similar to this in some dnr tv episodes.
I think it was Miguel Castro episodes 1 & 2, but it could be episode 31.
An archive of all the videos is here