10

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

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(这两个控件也有共同点)。

感谢您的想法!

4

3 回答 3

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

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

于 2013-04-30T07:53:20.917 回答
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
}

我希望这是一些帮助!

于 2013-04-30T07:53:51.937 回答
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
}
于 2013-04-30T07:54:40.527 回答