1

基本クラスを使用してコントロールの値/テキストにアクセスする方法はありますか?

TextBoxHiddenFieldを見ると、System.Web.UI.Control は、それらが共有する最も具体的な基本クラスです。良い候補のようですが、テキスト/値にアクセスする明確な方法がわかりません。

両方のクラス定義がControlValuePropertyAttributeを使用して、テキスト/値を保持するプロパティを識別していることがわかります...たとえば、HiddenField は「Value」に設定され、TextBox は「Text」に設定されます。ただし、その情報を使用してデータを取得する方法がわかりません。

バックグラウンド

Web コントロール (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 インターフェイスを実装していない) の値が必要です。関数をオーバーロードするのは簡単ですが、基本クラスを処理するだけで、オーバーロードを記述する必要がなくなるのはすばらしいことです。

編集 - 追加情報

拡張メソッドの使用例を次に示します。

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 プロパティとテキスト ボックスの Text プロパティを使用してデータにアクセスするため、これには 2 つのオーバーロードが必要です。

過負荷の何が問題になっていますか? ほぼ同じコードを何度も書いていることを除いて、何もありません(定義の最初のパラメーターとその呼び出しの最初の引数を変更するだけです)。

4

2 に答える 2

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);
}
于 2013-02-19T15:37:46.400 に答える
0

DataItemContainerがあなたが探しているものに最も近いと思います。

于 2013-02-19T15:29:46.083 に答える