WinForms ComboBox DataBound到Enum - 格式字符串

时间:2013-04-04 12:35:33

标签: .net winforms combobox enums string-formatting

这只是对来自ComboBox的{​​{1}}格式化字符串值的最佳方式的调查。

我知道我可以像这样将Enum数据绑定到ComboBox

Enum

结果如下:

enter image description here

我想格式化public partial class MainForm : Form { public MainForm() { InitializeComponent(); } protected override void OnLoad(EventArgs e) { comboBoxNames.DataSource = Enum.GetValues(typeof (Names)); } } public enum Names { JohnDoe, JaneDoe, JohnJackson, JackJohnson } 的显示值,以便PascalCase字符串值之间有空格,同时也传递我可以使用的所选项目的ComboBox值稍后发表Enum声明:

switch

我知道有switch ((Names)comboBoxNames.SelectedItem) { case Names.JohnDoe: // Do something John Doe-specific break; case Names.JaneDoe: // Do something Jane Doe-specific break; case Names.JohnJackson: // Do something John Jackson-specific break; case Names.JackJohnson: // Do something Jack Johnson-specific break; } 属性,但我不确定如何使用它来按照我想要的方式格式化ComboBox.FormatString枚举。

这可能吗?我宁愿不使用Names上的属性,因为使用它最终会涉及使用反射,这对于看起来如此简单的事情来说似乎有些过分。任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:1)

这很简单,只需在组合框中添加格式化事件,并使其如下所示:

private void comboBoxNames_Format(object sender, ListControlConvertEventArgs e)
{
    StringBuilder newText = new StringBuilder(e.Value.ToString().Length +1);
    newText.Append(e.Value.ToString()[0]);
    for (int i = 1; i < e.Value.ToString().Length; i++)
    {
        if (char.IsUpper(e.Value.ToString()[i]) && e.Value.ToString()[i - 1] != ' ')
            newText.Append(' ');
        newText.Append(e.Value.ToString()[i]);
    }
    e.Value = newText.ToString();
}

答案 1 :(得分:0)

我找到了一种格式化ComboBox来自我喜欢的Enum的字符串值的方法,而不需要ComboBox.FormatString属性或Format事件:使用Dictionary<Enum, string>。示例代码如下:

public partial class MainForm : Form
{
    public MainForm()
    {
        InitializeComponent();
    }

    protected override void OnLoad(EventArgs e)
    {
        comboBoxNames.DataBindToEnum(default(Names).ToDictionary());
    }

    private void btnOK_Click(object sender, EventArgs e)
    {
        switch (((KeyValuePair<Names, string>)comboBoxNames.SelectedItem).Key)
        {
            case Names.JohnDoe:
                // Do something John Doe-specific
                MessageBox.Show(@"John Doe!");
                break;
            case Names.JaneDoe:
                // Do something Jane Doe-specific
                MessageBox.Show(@"Jane Doe!");
                break;
            case Names.JohnJackson:
                // Do something John Jackson-specific
                MessageBox.Show(@"John Jackson!");
                break;
            case Names.JackJohnson:
                // Do something Jack Johnson-specific
                MessageBox.Show(@"Jack Johnson!");
                break;
        }
    }
}

public enum Names
{
    JohnDoe,
    JaneDoe,
    JohnJackson,
    JackJohnson
}

public static class EnumExtensions
{
    public static Dictionary<T, string> ToDictionary<T>(this T enumeration)
    {
        if (!enumeration.GetType().IsEnum) return null;

        var enumValues = Enum.GetValues(typeof(T)).OfType<T>().ToList();
        return enumValues.ToDictionary(enumValue => enumValue, enumValue => enumValue.ToString().Spaceify());
    }
}

public static class StringExtensions
{
    public static string Spaceify(this string self)
    {
        for (var i = 1; i < self.Length - 1; i++)
        {
            if (char.IsLower(self[i - 1]) && char.IsUpper(self[i]) ||
                self[i - 1] != ' ' && char.IsUpper(self[i]) && char.IsLower(self[i + 1]))
            {
                self = self.Insert(i, " ");
            }
        }
        return self;
    }
}

public static class ControlExtensions
{
    public static void DataBindToEnum<T>(this ListControl listControl, IDictionary<T, string> enumAsDictionary)
    {
        listControl.DataSource = new BindingSource(enumAsDictionary, null);
        listControl.DisplayMember = "Value";
        listControl.ValueMember = "Key";
    }
}

有几点需要注意:

  • 不是直接将ComboBox.DataSource设置为enum的列表,而是使用Dictionary<Enum, string>进行设置,并相应地设置DisplayMemberValueMember(扩展名)方法DataBindToEnum
  • 目前,我们无法将enum关键字用作类型限制(类似public static Dictionary<T, string> ToDictionary<T>(this T enumeration) **where T : enum**)。这就是为什么在该方法的正文中需要enum检查
  • Spaceify扩展方法为PascalCase字符串添加空格(也处理首字母缩略词)
  • “魔术”行是我在default上使用enum关键字的地方,因此我可以将其作为列表类型对象进行处理,并解决调用方法的问题。 enum
  • 的“实例
  • 最后,在使用ComboBox.SelectedItem时,我需要将其转换为KeyValuePair<Enum, string>并提取Key我可以在switch语句中使用的{{1}}。没有更多神奇的字符串了!

希望这有帮助!