2011-11-11 2 views
0

이것은 아마도 긴 샷이지만, 내가 작업하고있는 프로그램에서 반복을 최소화하려고 노력 중이며 걸림돌을 겪었습니다. 아래의 ClearTextBoxes() 메서드에서 볼 수 있듯이 foreach 루프 내에서 간결하게 배치하려는 코드는 매우 반복적입니다. 원래는 foreach (object box in customBoxes) 루프가 없었습니다. 나는 다음 목록으로 이것을 시도했지만 아무 소용이 없다. 나는 이것이 단지 불가능한 것인지, 아니면 단순히 잘못하고 있는지 확실하지 않습니다. 당신이 줄 수있는 도움을 주시면 감사하겠습니다.이 코드 블록을 축소하려면 어떻게해야합니까?변수의 List <>가 가능합니까?

감사합니다.

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

두 번째 루프의 역할은 무엇입니까 (foreach (customBoxes의 객체 상자) )? – 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

나는 이것을 시도하고이 접근법에 가장 가까운 성공을 거두었지만, 그 문제는 내가 생각하기에 그 목록을 추가하는 구문에서와 같이 그 List를 채우는 방법을 모른다는 것입니다. –

+0

@KevenM foreach (ccChildren.GetChildren (rvraDockPanel, 2) list.Add (o as MyClearable))의 객체를 사용 해본 적이 있습니까? 또한 해당 독 패널의 모든 컨트롤이 가지고있는 자손 유형인지 확인해야합니다 즉, 'ClearableDigitBox'등이 있습니다. – James

+0

그래, 그 중 하나를 작동시키지 못했습니다. 그러나 시도 할 때, 나는 생각을 가지고 있었고 아마도 이것이 효과가 있는지 여부를 확인할 수있었습니다. 내가 만든 두 번째 게시물에서 지적했듯이 digitbox, phonebox 및 datebox 간의 유일한 차이점은 IsFormattingKey 메소드의 존재입니다. 상속 된 클래스로 작성하는 대신 인터페이스를 사용할 수 있습니까? 왜냐하면 foreach 루프는 ** 단지 ** 대신 5 대신 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 = ""; 
     } 

사용자 정의 컨트롤은 당연히 텍스트 속성을 노출하는 단일 인터페이스 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 
관련 문제