I current开发者_JS百科ly have the following code:
Dim ucAppName As UserControl_appName = CType(Parent.FindControl(strucParam(i).ParentFindControl), UserControl_appName)
How can I modify it so that "UserControl_appName" is not hard coded. I would like to pass it as a string. Thanks!
Hints:
You'll need to pass a System.Type to your method ...
You'll need to use Object.GetType() and also the typeof operator. You can also create an instance of a Type of a class by using its qualified name if its in the currently executing assembly OR the AssemblyQualifiedName
Basic idea below:
WebForm
<h2>Passing Types</h2>
<asp:Panel runat="server" ID="pnl1">
<p>
<asp:TextBox runat="server" ID="txt1" />
</p>
<p>
<asp:DropDownList runat="server" ID="ddl1" />
</p>
<p>
<asp:HyperLink runat="server" ID="hl1" Text="Link1" NavigateUrl="http://www.google.co.uk" Target="_blank" />
</p>
</div>
<asp:Label runat="server" ID="lout" />
<div>
<p>
<asp:DropDownList runat="server" ID="ddlTypes">
</asp:DropDownList>
<asp:Button runat="server" ID="btnGetValueFromType" Text="Get Value By Control Type" onclick="btnGetValueFromType_Click" />
</p>
</asp:Panel>
CodeBehind (Apologies, its been quite a while since I did any VB.net so this example is in C#)
protected void Page_Load(object sender, EventArgs e)
{
if (! IsPostBack){
buildGui();
}
}
private void buildGui(){
List<string> lstStrings = new List<string>(5);
lstStrings.Add("one");
lstStrings.Add("two");
lstStrings.Add("three");
lstStrings.Add("four");
lstStrings.Add("five");
ddl1.DataSource = lstStrings;
ddl1.DataBind();
//Populate the Types Dropdown with some fullyqualified type names (includes the assembly name,version number, PublicKey etc.)
Dictionary<string, string> lstTypes = new Dictionary<string, string>(3);
lstTypes.Add(this.ddl1.GetType().Name, this.ddl1.GetType().AssemblyQualifiedName);
lstTypes.Add(this.txt1.GetType().Name, this.txt1.GetType().AssemblyQualifiedName);
lstTypes.Add(this.hl1.GetType().Name, this.hl1.GetType().AssemblyQualifiedName);
//lstTypes.Add(this.hl1.GetType().Name, this.hl1.GetType().AssemblyQualifiedName);
lstTypes.Add(this.CRJunk01.GetType().Name, this.CRJunk01.GetType().AssemblyQualifiedName);
ddlTypes.DataSource = lstTypes;
ddlTypes.DataValueField = "value";
ddlTypes.DataTextField = "key";
ddlTypes.DataBind();
}
protected void btnGetValueFromType_Click(object sender, EventArgs e)
{
Type t = Type.GetType(ddlTypes.SelectedValue);
lout.Text = "Looking for a type: " + t.ToString();
foreach(Control c in this.pnl1.Controls){
if (c.GetType().Equals(Type.GetType(ddlTypes.SelectedValue)))//Look for controls whose type is the same as the type selected in ddl1.
{
lout.Text += string.Format("<br/>Got Control of type: {0}", c.GetType().Name);
//Cast to your custom Interface/BaseClass and extract the value.
lout.Text += "<br/>Value is: " + ((ICrJunkControl)(c)).ControlValue;
}
}
}
This is the sort of thing you'll probably need to 'leverage'.
On a final note, it will probably be best if all your custom controls inherit from a base class or an interface. That way, when you've located the object you want based on its type you can cast it to the interface or base class and then get the value of a bespoke shared member e.g. ControlValue
. The implementation of your base classes will override this. This will help to overcome problems related to disparate controls having different members that expose their state.
e.g.
Textbox -> Text
DropdownList -> SelectedValue
Hyperlink -> Text/NavigateUrl
HTH,
Use an interface and implement it on your usercontrol. You can then cast your usercontrol to the interface and have all the common properties and methods available to you.
Public Interface ucInterface
Property textbox() As String
Function calculate() As Double
End Interface
Public Class UserControl_appName
Inherits System.Web.UI.UserControl
Implements ucInterface
Public Function calculate() As Double Implements ucInterface.calculate
Return 99 / 10
End Function
Public Property textbox() As String Implements ucInterface.textbox
Get
Return txtBox.text
End Get
Set(ByVal value As String)
txtBox.text = value
End Set
End Property
End Class
Public Class Test
Public Sub Test()
Dim ucAppName As ucInterface = CType(Parent.FindControl(strucParam(i).ParentFindControl), ucInterface)
ucAppName.textbox = "Test 1"
ucAppName.calculate()
End Sub
End Class
Check out system.Reflection. You can also retrieve objects from other assemblies, or even from referenced libraries. Of course, for this to work, you need to remember that this code returns a reference to an an "object". You will still have the poblem of either defining an interface which defeines the common implementaiton for all of your controls, or another means of type determination.
Imports System.Reflection
Public Class ObjectFactory
Public Shared Function NamedObject(ByVal ObjectName As String) As Object
Dim Assem = [Assembly].GetExecutingAssembly()
Dim MyType As Type = Assem.GetType(ObjectName.Trim)
Dim MyObject As Object = Nothing
Try
MyObject = Activator.CreateInstance(MyType)
Catch MyProblem As TargetInvocationException
MessageBox.Show(MyProblem.ToString)
End Try
Return MyObject
End Function
End Class
精彩评论