将控件视为ComboBox或TextBox

时间:2013-04-30 07:37:09

标签: c# .net generics

解决以下问题的最佳方法是什么?

foreach (Control control in this.Controls)
{
    if (control is ComboBox || control is TextBox)
    {
        ComboBox controlCombobox = control as ComboBox;
        TextBox controlTextbox = control as TextBox;

        AutoCompleteMode value = AutoCompleteMode.None;

        if (controlCombobox != null)
        {
            value = controlCombobox.AutoCompleteMode;
        }
        else if (controlTextbox != null)
        {
            value = controlTextbox.AutoCompleteMode;
        }

        // ...
    }
}

您认为获取AutoCompleteMode属性非常复杂。您可以假设我保证我有一个ComboBox或一个TextBox。

我的第一个想法是为 T 使用多种类型的泛型,但似乎这在.NET中是不可能的:

public string GetAutoCompleteModeProperty<T>(T control) where T: ComboBox, TextBox // this does not work, of course

可悲的是,两个控件都没有共同的基类。

注意:这是一个与最小化示例一起使用的更一般的问题。在我的情况下,我还想访问/操纵其他AutoComplete * -proprties(两个控件都有共同点)。

感谢您的想法!

3 个答案:

答案 0 :(得分:5)

dynamic currentControl =  control;
string text = currentControl.WhatEver;

但是,如果currentControl没有Wha​​tEver属性,它会引发异常(Microsoft.CSharp.RuntimeBinder.RuntimeBinderException)

答案 1 :(得分:1)

取决于您想要实现的目标。如果您只对text属性感兴趣,那么这实际上是从Control类继承的 - 因此您不需要强制转换对象。所以你只需要:

foreach (var control in this.Controls)
{
    value = control.Text;

    ...
}

但是,如果您需要更复杂的逻辑,则应考虑重新考虑控制流。我建议使用View / Presenter模型并单独处理每个事件 - 单一责任的方法可以大大降低复杂性。

如果您为视图指定了具有预期属性的界面 - 例如view.FirstName,view.HouseName或view.CountrySelection - 这样就隐藏了实现(即TextBox,ComboBox等)。所以:

public interface IMyView
{
    string FirstName { get; }
    string HouseName { get;}
    string CountrySelection { get; }
}

public class MyView : Form, IMyView
{
    public string FirstName { get { return this.FirstName.Text; } } // Textbox
    public string HouseName { get { return this.HouseName.Text; } } // Textbox
    public string CountrySelection { get { return this.CountryList.Text; } // Combobox
}

我希望有一些帮助!

答案 2 :(得分:1)

使用Type.GetType()。您只需输入您的财产的string表示。

if (sender is ComboBox || sender is TextBox)
{
  var type = Type.GetType(sender.GetType().AssemblyQualifiedName, false, true);
  var textValue = type.GetProperty("Text").GetValue(sender, null);
}

这也允许您设置属性的值。

type.GetProperty("Text").SetValue(sender, "This is a test", null);

您可以将其移动到辅助方法以保存重写代码。

public void SetProperty(Type t, object sender, string property, object value)
{
  t.GetProperty(property).SetValue(sender, value, null);
}
public object GetPropertyValue(Type t, object sender, string property)
{
  t.GetProperty(property).GetValue(sender, null);
}

使用此方法还有处理异常的空间。

var property = t.GetProperty("AutoCompleteMode");
if (property == null)
{
  //Do whatever you need to do
}