2011-11-11 3 views
0

これはおそらくロングショットですが、私が取り組んでいるプログラムでは繰り返しを最小限に抑えようとしています。下のClearTextBoxes()メソッドに見られるように、私はコードを非常に繰り返しているので、foreachループの内側に簡潔に配置することをお勧めします。 (もともとforeach (object box in customBoxes)ループはありませんでした)。私は以下のリストでこれをやろうとしましたが、役に立たなかった。私はこれがちょうどできないかどうか、または私がそれを間違ってやっているのかどうかはわかりません。私はあなたが与えることができる任意のヘルプに感謝し、これを行うことができない場合、どのように私はこのコードブロックを縮小することができますか?変数のリスト<>は使用できますか?

ありがとうございます!

List<object> customBoxes = new List<object>(); 

customBoxes.AddRange(new[] { "TextBox", "DateBox", "DigitBox", "PhoneBox", "WaterTextBox" }); 



public void ClearTextBoxes() 
    { 
     ChildControls ccChildren = new ChildControls(); 

     foreach (object o in ccChildren.GetChildren(rvraDockPanel, 2)) 
     { 
      foreach (object box in customBoxes) 
      { 
       if (o.GetType() == typeof(TextBox)) 
       { 
        TextBox txt = (TextBox)o; 
        txt.Text = ""; 
       } 

       if (o.GetType() == typeof(DigitBox)) 
       { 
        DigitBox digit = (DigitBox)o; 
        digit.Text = ""; 
       } 

       if (o.GetType() == typeof(PhoneBox)) 
       { 
        PhoneBox phone = (PhoneBox)o; 
        phone.Text = ""; 
       } 

       if (o.GetType() == typeof(DateBox)) 
       { 
        DateBox date = (DateBox)o; 
        date.Text = ""; 
       } 

       if (o.GetType() == typeof(WatermarkTextBox)) 
       { 
        WatermarkTextBox water = (WatermarkTextBox)o; 
        water.Text = ""; 
       } 
      } 
     } 
    } 
+2

各コントロールから継承し、ClearText()メソッドでインターフェイスを適用します。 – James

+0

2番目のループの役割は何ですか(foreach(カスタムボックス内のオブジェクトボックス) )? – DeveloperX

+0

あなたはこの質問を見ることができます:http://stackoverflow.com/questions/619767/net-reflection-set-object-property – GTG

答えて

0

私はClearText()方法でinterfaceを作成します。だから、それだけだ

class ClearableDigitBox : DigitBox, IClearable 
{ 
    public void ClearText() { 
    Text = String.Empty; 
    } 
} 
// etc... 

interface IClearable 
{ 
    public void ClearText(); 
} 

その後、各コントロールから継承し、そのインターフェイスを適用することができます

var list = new List<IClearable>; 
// ... 
foreach (IClearable control in list) control.ClearText(); 
+0

私はこれを試して、このアプローチで成功に最も近づいてきましたが、問題は、リストを追加する構文がそうであるように、リストを作成する方法がわからないということです。 –

+0

@KevenM 'foreach(ccChildren.GetChildren(rvraDockPanel、2)のオブジェクトo)list.Add(MyClearableとしてo)を試したことがありますか? 'また、そのドックパネルのすべてのコントロールが自分の子孫タイプであることを確認する必要がありますつまり、 'ClearableDigitBox'などです。 – James

+0

ええ、それを動作させることができませんでした。しかし、試してみると思っていましたが、これがうまくいくかどうかを検証することができます。私が作成した2番目の記事で指摘したように、digitbox、phonebox、およびdateboxの唯一の違いは、 'IsFormattingKey'メソッドの存在です。それらを継承したクラスとして記述するのではなく、それらのインタフェースを使用できますか?そのため、foreachループは単に**の代わりに**の代わりに1つのタイプのcustomboxを参照できますか? –

0

あなたは、いくつかのductypingの動作を模倣するために、いくつかの方法で、リフレクションを使用することができますが、それはパフォーマンスと醜いではありませんので、私はその解決のために行くwouldntは。

 foreach (object box in customBoxes) 
     { 
      var boxType = box.GetType(); 
      var textProperty = boxType.GetProperty("Text"); 
      if (textProperty != null && textProperty.CanWrite) 
      { 
       textProperty.SetValue(box, "", null); 
      } 
     } 

それとも、同じ結果を達成するために、動的に使用することができます

 foreach (dynamic box in customBoxes) 
     { 
      box.Text = ""; 
     } 

カスタムコントロールはofcourseのは、textプロパティを公開する単一のインタフェースIWithTextPropertyを実装させることであろう移動するための方法。

+0

リフレクションは、私が一度も聞いたことがない最後のカップルの日までに投稿を検索しています:)それは間違いなく私が見なければならないものです...ダイナミックでも同じです。そして、私はインターフェースが不安定です。どこにでもインターフェイスに関する非常に基本的なガイドがありますか? –

1
List<Type> customBoxes = new List<Type>(); 

customBoxes.AddRange(new[] { typeof(PhoneBox), typeof(DigitBox), ....." }); 

foreach (Control c in this.Controls) 
{ 
    if (customBoxes.Contains(c.GetType())) 
    { 
    c.Text = string.Empty; 
    } 
} 
+0

これは、すべての 'customBoxes'が' Control'を継承するという(おそらく正しい)仮定をしていると言及するべきですが、OPはこれではっきりしませんでした。 –

+0

申し訳ありませんが、私はそれが明確ではないが、実際にはコントロールを継承していません(少なくとも私はそうは思わない)。それらはExtendedToolkit dllのWatermarkTextBoxから継承します。そして私がこのアプローチを試みたとき、.Controlsの部分は、コントロールという名前の定義や拡張メソッドがないというエラーを出しました。 –

0

は、すべての入力ボックスコントロールオブジェクトの一部ではありませんか?

もしそうなら、あなたは、私はおそらくのような方法だろうコントロール からすべてのテキストをクリアしたい:あなただけの特定の種類のコントロールを検索したい場合は

public void ClearText(List<Control> items) 
    { 
     foreach (Control control in items) 
     { 
      control.Text = string.Empty; 
     } 
    } 

public void ClearText(List<Control> items) 
     { 
      foreach (Control control in items) 
      { 
       if (control is TextBox) 
        ((TextBox)control).Text = string.Empty; 
       else if (control is DigitBox) 
        ((DigitBox)control).Text = string.Empty; 
       else 
       { // Handle anything else.} 
      } 
     } 
0

これまでのいくつかの返信に応じて、これは私がカスタムボックス用に持っているクラスファイルです。 NumberTextBoxクラスは、VSが追加したデフォルトスニペットです。私はそれを使用していない、それも削除されていない。スペースを節約するために折りたたまれているDateBoxに加えて、DigitBoxから継承するPhoneBoxクラスもあります。 DigitBoxが継承するWatermarkTextBoxクラスは、WpfToolkit.Extended.dllにあります。これらのクラスの唯一の違いは、書式設定のキーが押されていることを許可/禁止するメソッド(かっこ、ピリオド、ハイフンなど)が追加されていることです。

このクラスは基本的に、私がウェブ上で見つけたいくつかの異なるスニペットをマージしようとした結果生じました。しかし、これらのボックスの目的は透かしを有効にし、それらのボックスに入力できる文字を制限することです。

public class NumberTextBox : Control 
{ 
    static NumberTextBox() 
    { 
     DefaultStyleKeyProperty.OverrideMetadata(typeof(NumberTextBox), new FrameworkPropertyMetadata(typeof(NumberTextBox))); 
    } 

}  

public class DigitBox : WatermarkTextBox, IClearable 
{ 
    #region Constructors 
    ///<summary> 
    ///The default constructor 
    /// </summary> 
    public DigitBox() 
    { 
     TextChanged += new TextChangedEventHandler(OnTextChanged); 
     KeyDown += new KeyEventHandler(OnKeyDown); 
     PreviewKeyDown += new KeyEventHandler(OnPreviewDown); 
    } 
    #endregion 

    #region Properties 
    new public String Text 
    { 
     get { return base.Text; } 
     set 
     { 
      base.Text = LeaveOnlyNumbers(value); 
     } 
    } 
    #endregion 

    #region Functions 
    public bool IsNumberKey(Key inKey) 
    { 
     if (inKey < Key.D0 || inKey > Key.D9) 
     { 
      if (inKey < Key.NumPad0 || inKey > Key.NumPad9) 
      { 
       return false; 
      } 
     } 
     return true; 
    } 

    public bool IsActionKey(Key inKey) 
    { 
     return inKey == Key.Delete || inKey == Key.Back || inKey == Key.Tab || inKey == Key.Return; 
    } 

    public string LeaveOnlyNumbers(String inString) 
    { 
     String tmp = inString; 
     foreach (char c in inString.ToCharArray()) 
     { 
      if (!IsDigit(c)) 
      { 
       tmp = tmp.Replace(c.ToString(), ""); 
      } 
     } 
     return tmp; 
    } 

    public bool IsSpaceKey(Key inKey) 
    { 
     if (inKey == Key.Space) 
     { 
      return true; 
     } 
     return false; 
    } 

    public bool IsDigit(char c) 
    { 
     return (c >= '0' || c <='9'); 
    } 
    #endregion 

    #region Event Functions 
    protected virtual void OnKeyDown(object sender, KeyEventArgs e) 
    { 
     e.Handled = !IsNumberKey(e.Key) && !IsActionKey(e.Key) && !IsSpaceKey(e.Key); 
    } 

    protected virtual void OnTextChanged(object sender, TextChangedEventArgs e) 
    { 
     base.Text = LeaveOnlyNumbers(Text); 
    } 

    protected virtual void OnPreviewDown(object sender, KeyEventArgs e) 
    { 
     if (e.Key == Key.Space) 
     { 
      e.Handled = true; 
     } 
    } 
    #endregion 
} 


public class DateBox : DigitBox 
関連する問題