是一个列表<>可能的变量

本文关键字:变量 列表 一个 | 更新日期: 2023-09-27 18:14:16

这可能是一个很长的机会,但我正在努力减少我正在工作的程序中的重复,并且遇到了一个障碍。从下面的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 = "";
                }
            }
        }
    }

是一个列表<>可能的变量

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;
  }
}

我将创建一个带有ClearText()方法的接口。

interface IClearable
{
  public void ClearText();
}

那么你可以从每个控件继承并应用该接口:

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

就是:

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

您可以使用反射以某种方式模仿一些ductyping行为,但我不会采用这种解决方案,因为它既不性能又不美观。

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

或者您可以使用dynamic来达到相同的结果:

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

方法是让你的自定义控件实现一个单一的接口IWithTextProperty,它当然会暴露文本属性

是不是所有的输入框都是Control对象的一部分?

(如果是),并且希望清除控件中的所有文本然后我可能会有这样一个方法:

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.}
            }
        }

为了回应到目前为止的几个回复,这是我为自定义框准备的类文件。NumberTextBox类是VS添加的默认代码片段。我没有使用它,只是也没有删除它。除了DateBox(为了节省空间而折叠)类之外,还有一个PhoneBox类,它也继承自DigitBox。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