这只是对来自ComboBox
的{{1}}格式化字符串值的最佳方式的调查。
我知道我可以像这样将Enum
数据绑定到ComboBox
:
Enum
结果如下:
我想格式化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
上的属性,因为使用它最终会涉及使用反射,这对于看起来如此简单的事情来说似乎有些过分。任何帮助将不胜感激。
答案 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>
进行设置,并相应地设置DisplayMember
和ValueMember
(扩展名)方法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}}。没有更多神奇的字符串了!希望这有帮助!