2013-02-19 4 views
1

기본 클래스를 사용하여 컨트롤의 값/텍스트에 액세스하는 방법이 있습니까?System.Web.UI.Control (기본 클래스)에서 값을 가져 오는 방법은 무엇입니까?

TextBoxHiddenField에서 볼 때 System.Web.UI.Control은 공유하는 가장 구체적인 기본 클래스입니다. 좋은 후보자 같지만 텍스트/값에 액세스하는 확실한 방법은 없습니다.

두 클래스 정의 모두 ControlValuePropertyAttribute을 사용하여 텍스트/값을 보유하고있는 속성을 식별하는 것을 볼 수 있습니다. HiddenField가 "Value"로 설정되고 TextBox가 "Text"로 설정됩니다. 데이터를 검색하기 위해 해당 정보를 사용하는 방법을 모르겠다.

배경

내가 일부 웹 컨트롤의 텍스트 (예를 들어, 텍스트 상자)를 받아 지정된 형식으로 변환 확장 방법이 : 이제

<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 인터페이스를 구현하지 않음) 함수에 과부하가 걸리기는 쉽지만 기본 클래스를 처리하고 더 이상 오버로드를 처리하지 않아도됩니다.

편집 - 데이터 값 hiddenfields의 속성과를 사용하여 액세스하기 때문에 추가 정보를 원하시면 여기

이 확장 방법은 현재

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 

을 사용하는 방법의 예입니다,이 두 가지 오버로드가 필요합니다 텍스트 상자의 텍스트 속성.

과부하의 문제점은 무엇입니까? 아무것도 제외하고 거의 동일한 코드를 반복적으로 작성하고 있습니다 (정의의 첫 번째 매개 변수와 해당 호출의 첫 번째 인수 만 수정하면됩니다).

답변

4

데이터를 가져올 수있는 상속 트리에 공통 조상이 없으므로 객체 지향 접근 방식을 사용하여 값을 가져올 수 없습니다. 솔루션은 너무 우아하여 WebControl을 전달하고 유형을 동적으로 확인해야합니다.

사면 내 C# :

(나는 그래서 당신은 약간의 개조하면 되겠 어해야 할 수도 있습니다 그 중 하나를 실행하지 않은,이 메모장 코드가 있습니다)


해결 방법 1 :에서 직접 데이터를 가져옵니다 요청

단점 :별로 ASP.NET-ish. 그러나 그 일을합니까?

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

그것은 라벨 또는에 HiddenField가 IDataItemContainer를 구현 중 하나처럼 보이지 않는에 속도가 느려질 수 있습니다. 그들은 속성을 가지고 있지만 인스턴스는 null/Nothing for myControl.DataItemContainer –

+0

아마 더 나은 솔루션은 여러 컨트롤을 사용할 필요가있는 특정 컨트롤에 대한 여러 확장 메서드를 만드는 것일 수 있습니다. 특히 당신이하려고하는 것입니다. –

+0

현재 여러 확장 메서드가 있으며 공통 논리는 자체 함수 인 ConvertValue에 있습니다. 그냥 컨트롤 특정 메서드를 통합하는 방법을 찾고 (정말 문제가 아니라, 적은 코드 == 더 나은) –