2017-05-09 13 views
0

とコントロールの種類だから私は、次のクラスを持って...マッチ基底クラス

public partial class CommandBar : UserControl { .. } 

...目標は、ユーザーがすべてのコントロールを再帰的に読み取り専用に設定できる汎用メソッドを作成することです。メソッドは無視するコントロールのList<Type>を指定するオプションのパラメーターを提供する必要があります。このリストでは、このCommandBarをtypeof(CommandBar)に渡して無視するようにしたいと考えています。

すべてが期待どおりに機能しますが、これらのタイプに一致する正しい方法を迷惑にしています。

以下を考慮してください。

Object o; // control to check, in this case the `CommandBarTop` object 
Type t; // type to ignore 

私はそれがこのように簡単であることが予想:

if (o is t){ 
    // ignore 
} 

...しかし、私は、「一定の値が期待されている」構文例外を取得します。だから私は次のセットアップでそれを試した:

if (t == typeof(o)){ 
    // ignore 
} 

それはコンパイルしましたが、期待どおりに動作しませんでした。この問題はタイプミスマッチと思われます。私は、次を取得し、デバッガを見てみる:

t => {Name = "CommandBar" FullName = "My.Name.Space.Controls.CommandBar"} System.Type {System.RuntimeType} 
o => {ASP.controls_commandbar_ascx} object {ASP.controls_commandbar_ascx} 

o.baseはタイプtで実際にあるが、常におそらくないだろう最初のすべてのそれはアクセスできず、第2の方法は、一般的なあるべき、と一致するように基本型をチェックします私がしたいことをやりなさい。

ASP.NETが実行時にコントロールラッパーを生成し、それがユーザーに送信されると仮定します。この前提は、デバッガに表示されるアセンブリコードベースに基づいています。それは、次の言葉:

t.Assembly.CodeBase => "file:///.../bin/My.Name.Space.Project.DLL" string 
o.GetType().Assembly.CodeBase => "file:///C:/Windows/Microsoft.NET/Framework/.../Temporary ASP.NET Files/root/.../App_Web_....DLL" string 

私はまたタイプのGUIDを照合しようとしたが、彼らは基本的にはどちらか動作しません同じタイプではないので。


EDIT 1

私はあなたを再帰的に

今、私の質問に来
public static void SetControlRecursivelyReadOnly(Object control, Boolean readOnly, IEnumerable<Type> controlTypesToIgnore = null) 
{ 
    if (null == control) 
    { 
     return; 
    } 

    new List<KeyValuePair<Type, String>> 
    { 
     // define all types which are relevant to access possible child controls 
     new KeyValuePair<Type, String>(typeof(ControlCollection), "Controls"), 
     new KeyValuePair<Type, String>(typeof(TableRow), "Rows"), 
     new KeyValuePair<Type, String>(typeof(TableCell), "Cells") 
    }.ForEach(x => 
       { 
        // get defined property 
        Object property = typeof(Reflection).GetMethod("GetProperty") 
                 .MakeGenericMethod(x.Key) 
                 .Invoke(null, 
                   new[] 
                   { 
                    control, 
                    x.Value 
                   }); 

        // check if property is found and is IENumerable 
        if (!(property is IEnumerable)) 
        { 
         return; // continues the foreach loop 
        } 

        // call recursive 
        foreach (Object o in (IEnumerable) property) 
        { 
         // <--- TODO CHECK IF CONTROL TYPE SHOULD BE IGNORED ---> 
         SetControlRecursivelyReadOnly(o, readOnly); 
        } 
       }); 

    // set relevant properties accordingly to readOnly parameter 
    new List<Tuple<PropertyInfo, Boolean>> 
      { 
       new Tuple<PropertyInfo, Boolean>(control.GetType().GetProperty("ReadOnly"), readOnly), 
       new Tuple<PropertyInfo, Boolean>(control.GetType().GetProperty("EnableButtons"), !readOnly), 
       new Tuple<PropertyInfo, Boolean>(control.GetType().GetProperty("Enabled"), !readOnly) 
      }.Where(x => null != x.Item1) 
      .ToList() 
      .ForEach(x => x.Item1.SetValue(control, x.Item2, null)); 
} 

を読み取り専用するためのコントロールを設定するための私の方法を示した場合、それが役立つかもしれないと思いました。誰もがこの問題を解決する方法を知っていますか?

ありがとうございます!

+0

を動作するはず?たぶん "コントロール"(テキストボックス、ラベル...)?いくつかの例を追加できますか? – Emanuele

+0

@Emanueleはい先生、私は、コントロールを意味します。私はそれに応じて私の質問を更新しました。あなたがTextBox、Label asoで与えた例。まさに私が意味するものです。また、パネル、テーブル、DropDownLists ..時々プロパティは、「コントロール」と呼ばれている、「行」または「セル」themselfsがあるOFC私は私が既に持っているページ –

答えて

0

ページ内のすべてのコントロールを再帰的にループする必要があります。

public void FindChildControlsRecursive(Control control) 
    { 
     foreach (Control childControl in control.Controls) 
     { 
      // add .BaseType in the next line if it's a UserControl 
      if (childControl.GetType() == typeof(T)) 
      { 
       _foundControls.Add((T)childControl); 
      } 
      else 
      { 
       FindChildControlsRecursive(childControl); 
      } 
     } 
    } 

    private readonly List<T> _foundControls = new List<T>(); 
    public IEnumerable<T> FoundControls 
    { 
     get { return _foundControls; } 
    } 

同様に、除外するコントロールを含むプロパティを設定できます。

次のことが確認できます。How to get the "typeof" of a custom user control

+0

内のすべてのコントロールに到達するために再帰的にそれを実装する理由、thatsの再帰関数、それは問題ではありません。問題は型の一致です。 'control.GetType()== typeof(T)'でのあなたのアプローチはうまくいきません。 Tはすでにタイプですので、typeof演算(T)を呼び出すと、私は必要なものではありませんRuntimeTypeを返します。また、コントロールが動作しない同じ型でないためです。もう一度私の質問を読んで –

+0

申し訳ありませんが、私は自分の投稿を編集したいです。 BaseTypeを使用してみてください。私はVS上で自分のソリューションをチェックしたいと思います。 – Emanuele

+0

はい、BaseTypeは、実際に動作する必要があり、これに一致する、正しいタイプを指します。問題は、BaseTypeを常にチェックするために実装すると、ほとんどすべてのコントロールのBaseTypeが 'WebControl'なので、これはほとんどの場合にはうまくいきません。WebControlを無視するようにメソッドに指示すると何も起こりません。私はすでにこのアプローチを考えたが、私が私の解決策を確認し –

0

はあなたのタイプの名前の小道具で試してみてください。以下のような何かを使用すると、コンポーネントについて話すとき、あなたが何を意味する

if (typeof(o).Name == t.GetType().Name) { // ignore }

+0

を '.GetType()'を(これは 'Type'の型である)呼び出して実装しようとしています。 'System.RuntimeType'を返します。これは動作しません。名前も同じではありません –

関連する問題