Возможен ли список <> переменных? - PullRequest
0 голосов
/ 11 ноября 2011

Это, вероятно, длинный выстрел, но я пытаюсь свести к минимуму повторение в программе, над которой я работаю, и столкнулся с проблемой. Как видно из метода ClearTextBoxes () ниже, у меня есть очень повторяющийся фрагмент кода, который я бы предпочел поместить в цикл foreach для краткости. (Изначально петли foreach (object box in customBoxes) там не было). Я пытался сделать это с помощью следующего списка, но безрезультатно. Я не уверен, что это просто невозможно, или я просто делаю это неправильно. Я был бы признателен за любую помощь, которую вы могли бы оказать, и если это невозможно, то как я могу уменьшить этот блок кода?

Спасибо! * * 1004

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

Ответы [ 5 ]

1 голос
/ 11 ноября 2011
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 голосов
/ 11 ноября 2011

В ответ на пару ответов на данный момент это файл класса, который я имею для пользовательских ящиков. Класс NumberTextBox является фрагментом по умолчанию, добавленным VS. Я не использовал его, просто не удалил его тоже. В дополнение к классу DateBox (который свернут для экономии места), есть также класс PhoneBox, который также наследуется от DigitBox. класс WatermarkTextBox, от которого наследуется DigitBox, находится в файле 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
0 голосов
/ 11 ноября 2011

Разве все поля ввода не являются частью объекта 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.}
            }
        }
0 голосов
/ 11 ноября 2011

Я бы создал интерфейс с методом 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();
0 голосов
/ 11 ноября 2011

Вы могли бы использовать отражение каким-то образом, чтобы имитировать какое-либо поведение при типизации каналов, но я бы не стал использовать это решение, поскольку оно не является производительным и некрасивым.

        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, который, конечно, предоставляет свойство text.

...