4 回答
Create an interface containing all your controls methods
public interface IMyControl
{
public void clear();
public string getastringvalue();
etc......
}
Get all your controls to inherit from this interface:
public class MyControl : UserControl, IMyControl
Cast all your controls to the interface:
private void button1_Click(object sender, EventArgs e)
{
IMyControl typedControl = hActiveUsrCtrl as IMyControl;
typedControl.Clear();
etc...
}
On a side not Reflection is inefficient and should be avoided where possible!
UserControls are implemented as classes, so you can have that class implement an interface, and just call the GetData method that way.
public interface IGetData {
string GetData(parameters ...);
}
public class MyUserControl : UserControl, IGetData {
...
}
If all the User Controls can have the same signature for the GetData method, you don't even have to figure out which type it is, just cast it to IGetData.
IGetData getable = activeCtrl as IGetData;
if (getable != null) {
var data = getable.GetData(...);
// do stuff with data
} else {
throw new ApplicationException("activeCtrl was null or didn't implement IGetData");
}
Update:
If I understand, it looks like you need an intermediate variable.
// newUc implements IGetData, not hActiveUsrCtrl
IGetData newUc = hActiveUsrCtrl.GetActiveUsrCtrl(parent.appInfo.catalogId, parent);
pUserControlContainer.Controls.Add((Control)newUc);
var data = newUc.GetData(parameters ...);
If all control have the same public methods etc., why do you not use an interface?
You may implement a control factroy class ControlFactory.GetUserSelectionControl() . This method creates at runtime the best control matching the selection of the user. You can pass in an input of a kind to identify the best control. And all controls implement in your case the same interface. Then you can directly call the methods without reflection. But in the meantime you got already an example on how to implement the interfaces.
If all the user control have the same methods, declare an interface, inherit from it, and cast to the interface.
something along the lines of :
ascx.cs file :
public partial class AleaPoisson : UserControl, ISymboleAlea {
public void SomeFunction();
...
}
aspx.cs file :
( conteneur should be a PlaceHolder control and it should be loaded on Page_Init, rather than Page_Load if possible )
var ctl = conteneur.Page.LoadControl( path );
conteneur.Controls.Add( ctl );
((ISymboleAlea)ctl).SomeFunction();