2013-02-19 4 views
1

Есть ли способ получить доступ к значению/тексту элемента управления с использованием базового класса?Как получить значение из System.Web.UI.Control (базовый класс)?

Глядя на TextBox и HiddenField, System.Web.UI.Control - это наиболее специфический базовый класс, который они разделяют. Кажется хорошим кандидатом, но я не вижу очевидного способа доступа к тексту/ценности.

Я вижу, что оба определения классов используют ControlValuePropertyAttribute, чтобы идентифицировать свойство, которое хранит их текст/значение ... например. У HiddenField установлено значение «Значение», для TextBox установлено значение «Текст». Не уверен, как использовать эту информацию для извлечения данных.

фон

У меня есть метод расширения, который принимает текст некоторых веб-управления (например, TextBox) и преобразует его в заданный тип:

<Extension()> _ 
Public Function GetTextValue(Of resultType)(ByVal textControl As ITextControl, ByVal defaultValue As resultType) As resultType 
    Return ConvertValue(Of resultType)(textControl .Text, defaultValue) 
End Function 

Теперь я нужен значение HiddenField (которое не реализует интерфейс ITextControl). Было бы легко перегрузить функцию, но было бы просто просто обработать базовый класс и больше не иметь дело с записью перегрузок.

Edit - дополнительная информация

Вот пример того, как метод расширения используется

Dim myThing as Decimal = tbSomeWebControl.GetTextValue(Of Decimal)(0) ' Converts the textbox data to a decimal 
Dim yourThang as Date = hdnSomeSecret.GetTextValue(Of Date)(Date.MinValue) ' Converts the hiddenfield data to a Date 

В настоящее время, это требует две перегрузки, так как осуществляется доступ к данным, используя свойство Value в hiddenfields и тому Текстовое свойство в текстовых файлах.

Что случилось с перегрузками? Ничего, кроме того, что я пишу почти один и тот же код снова и снова (просто изменяя первый параметр определения и 1-й аргумент его вызова).

ответ

4

Вы не можете использовать объектно-ориентированный подход для получения значения, потому что у них нет общего предка в дереве наследования, из которого вы можете извлекать данные. Решения настолько неэффективны, что вы должны просто пройти WebControl и проверить тип динамически.

Пардон мой C#:

(обратите внимание, что это блокнота код, я не запускать какой-либо из него, так что вы, возможно, потребуется несколько щипков)


Решение 1: Получение данных непосредственно из Запрос

Даунсайд: Не очень ASP.NET-иш. Но есть ли работа.

public string GetTextValue<ResultType>(WebControl control, ResultType defaultValue) 
{ 
    // If you only wish data from form, and not questy string or cookies 
    // use Request.Form[control.UniqueId] instead 
    string value = Request[control.UniqueId]; 
    return ConvertValue<ResultType>(value, defaultValue); 
} 

Решение 2: Проверьте тип динамически

Даунсайд: вы должны обеспечить обработку для нескольких типов управления

public string GetTextValue<ResultType>(WebControl control, ResultType defaultValue) 
{ 
    if (control is ITextControl) 
     return ConvertValue<ResultType>((ITextControl)control.Text, defaultValue); 
    else if (control is HiddenField) 
     return ConvertValue<ResultType>((HiddenField)control.Value, defaultValue); 
    else if (anothertype) 
     return ConvertValue<ResultType>(another_retrieval_method, defaultValue); 
} 

Решение 3: Используйте отражение

Даунсайд: отражение может быть сложно, не выглядит элегантно, и может быть медленным на многих заклятий

public string GetTextValue<ResultType>(WebControl control, ResultType defaultValue) 
{ 
    // Get actual control type 
    Type controlType = control.GetType(); 
    // Get the attribute which gives away value property 
    Attribute attr = controlType.GetCustomAttribute<ControlValuePropertyAttribute>(); 
    if (attr == null) 
     throw new InvalidOperationException("Control must be decorated with ControlValuePropertyAttribute"); 
    ControlValuePropertyAttribute valueAttr = (ControlValuePropertyAttribute)attr; 
    // Get property name holding the value 
    string propertyName = valueAttr.Name; 
    // Get PropertyInfo describing the property 
    PropertyInfo propertyInfo = controlType.GetProperty(propertyName); 
    // Get actual value from the control object 
    object val = propertyInfo.GetValue(control); 
    if (val == null) 
     val = ""; 

    return ConvertValue<ResultType>(val, defaultValue); 
} 
0

Я думаю, что DataItemContainer будет самой близкой вещью, которую вы ищете.

+0

Он не похож ни этикетки или скрытое реализовать класс IDataItemContainer. У них есть свойство, но экземпляры возвращают null/Nothing для myControl.DataItemContainer –

+0

Возможно, лучшим решением могло бы стать создание нескольких методов расширения для конкретных элементов управления, которые вам нужны для его использования, хотя я не совсем понимаю, что в частности, вы пытаетесь сделать. –

+0

В настоящее время у меня есть несколько методов расширения, а общая логика - в своей собственной функции ConvertValue. Просто ищите способ консолидации специфичных для управления методов (на самом деле это не проблема, а только код лучше) –

Смежные вопросы