locked
Method with a generic parameter RRS feed

  • Question

  • User-1136635841 posted

    Hi there

    I have these two methods that return the Text of some controls on my GridView :

    private string GetLiteralValue(string controlId)
    {
      Literal control = (Literal)myGridView.SelectedRow.FindControl(controlId);
      return control.Text;
    }

     

    private string GetTextBoxValue(string controlId)
    {
      TextBox textbox = (TextBox)myGridView.SelectedRow.FindControl(controlId);
      return textbox.Text;
    }

    Instead, I would like to have a generic method that would look for the type of control I specify when calling it. Something like this :

    private string GetControlValue<T>(string controlId)
    {
      T control = (T)myGridView.SelectedRow.FindControl(controlId);
      return control.Text;
    }

    This won't compile however, since the T type does not have a Text property. I also tried this :

    private string GetControlValue<T>(string controlId) where T : WebControl

    But it's not working either.

    Is there something that I forgot to add in my method, so that the compiler knows that my T type can be any WebControl with a Text property ?

    Thanks

    Friday, February 1, 2008 12:54 PM

Answers

  • User437720957 posted

    private string GetControlValue<T>(string controlId) where T : System.Web.UI.ITextControl

     

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Friday, February 1, 2008 1:04 PM
  • User1187105292 posted

    in the where clause that goes with T, you can specify that T implements a given class and/or that it implements one or more interfaces.

    The trick is to find one class or interface that guarantees the Text property.

    By "Going to Definition" on a Textbox and a DropDownList (and working up the chain of super-classes for DropDownList), I found both of these controls implement the ITextControl interface. 

    This interface looks like this:

    using System;

    namespace System.Web.UI

    {

    // Summary:

    // Defines the interface a control implements to get or set its text content.

    public interface ITextControl

    {

    // Summary:

    // Gets or sets the text content of a control.

    //

    // Returns:

    // The text content of a control.

    string Text { get; set; }

    }

    }

     So, specify that T must implement this interface and I think you'll be in good shape.

     

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Friday, February 1, 2008 1:20 PM
  • User437720957 posted

    That doesn't make sense to me, isn't Literal a WebControl ?

    Nope.  Literal only inherits from Control. But, you won't need that part anyway....

     

     

    private string GetControlValue<T>(string controlId) where T : ITextControl
    {
        ITextControl ctrl = myGridView.SelectedRow.FindControl(controlId) as ITextControl;
        if (ctrl!=null)
            return ctrl.Text;
        return string.Empty;
    }</T>
     

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Monday, February 4, 2008 7:06 AM

All replies

  • User437720957 posted

    private string GetControlValue<T>(string controlId) where T : System.Web.UI.ITextControl

     

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Friday, February 1, 2008 1:04 PM
  • User1187105292 posted

    in the where clause that goes with T, you can specify that T implements a given class and/or that it implements one or more interfaces.

    The trick is to find one class or interface that guarantees the Text property.

    By "Going to Definition" on a Textbox and a DropDownList (and working up the chain of super-classes for DropDownList), I found both of these controls implement the ITextControl interface. 

    This interface looks like this:

    using System;

    namespace System.Web.UI

    {

    // Summary:

    // Defines the interface a control implements to get or set its text content.

    public interface ITextControl

    {

    // Summary:

    // Gets or sets the text content of a control.

    //

    // Returns:

    // The text content of a control.

    string Text { get; set; }

    }

    }

     So, specify that T must implement this interface and I think you'll be in good shape.

     

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Friday, February 1, 2008 1:20 PM
  • User1187105292 posted

    Forgot to add that when you don't get lucky like that, you can always subclass a control and have your subclass(es) implement the interface you need (which  you also might have just created).  Then drag the subclass onto the page instead of TextBox, etc.

    Friday, February 1, 2008 1:21 PM
  • User-1136635841 posted

    Hi guys

    Thanks for you answers.

    I tried with ITextControl, then I got this compilation error :

    Cannot convert type 'System.Web.UI.Control' to 'T' 

    So I also added the WebControl class in the "where" clause :

    private string GetControlValue<T>(string controlId) where T : WebControl, ITextControl

    Now my code compiles, it works when T is a TextBox or a DropDownList, however it doesn't work with Literal controls : if I try

    string name = GetControlValue<Literal>("ltrName");

    I get the following error :

    The type 'System.Web.UI.WebControls.Literal' must be convertible to 'System.Web.UI.WebControls.WebControl' in order to use it as parameter 'T' in the generic type or method 'GetControlValue<T>(string)'

    That doesn't make sense to me, isn't Literal a WebControl ? I also tried with the LiteralControl class but I get the same error

    Monday, February 4, 2008 4:30 AM
  • User437720957 posted

    That doesn't make sense to me, isn't Literal a WebControl ?

    Nope.  Literal only inherits from Control. But, you won't need that part anyway....

     

     

    private string GetControlValue<T>(string controlId) where T : ITextControl
    {
        ITextControl ctrl = myGridView.SelectedRow.FindControl(controlId) as ITextControl;
        if (ctrl!=null)
            return ctrl.Text;
        return string.Empty;
    }</T>
     

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Monday, February 4, 2008 7:06 AM
  • User312496708 posted

    If that is your requirement then you class decleration should be

    private string GetControlValue<T>(string controlId) where T :  ITextControl

    You cannot allow T to be any control but only those which implements ITextControl interface

    Monday, February 4, 2008 7:15 AM
  • User-1136635841 posted

    Hello

    I actually changed my method so that it returns the control itselft instead of just its content (because sometimes I need to use the SelectedValue and DataSource properties of the controls I retrieve)

    Since Literal inherits from Control I changed the where clause the following way :

    private T GetControl<T>(string controlId) where T : Control, ITextControl

    So now it works with every kind of control

    Thanks for you help everyone !

     

    Monday, February 4, 2008 9:51 AM