C# DataGridView/ComboBox需要两种显示状态(长和短)来获取信息
我有一个DataGidView,它在水平空间上非常紧凑,还有一个专栏有相当长的描述 我想做的是创建一个组合框列:C# DataGridView/ComboBox需要两种显示状态(长和短)来获取信息,c#,winforms,user-interface,datagridview,C#,Winforms,User Interface,Datagridview,我有一个DataGidView,它在水平空间上非常紧凑,还有一个专栏有相当长的描述 我想做的是创建一个组合框列: 显示说明的缩短版本 在下拉列表中有完整的描述 幕后处理的是实际价值 举个例子,我在下面有一个人为的例子。真正的列表可以有20-30个项目,其中包含相当长的文本: Code Short DropDown Text 1 BigBox Boxes larger than 6' x 6' 2 SmBox Boxes smaller t
Code Short DropDown Text
1 BigBox Boxes larger than 6' x 6'
2 SmBox Boxes smaller than 6' x 6'
3 BigBrl Barrel 55 gallons
4 SmBrl Barrel less than 55 gallons
所以我想展示的是:
当我打开下拉列表时,我想看到:
当然,当我查询单元格的值时,我想要“1”
我可以分门别类,把“短”描述作为较长描述的第一部分(“大于6'x 6'”的BigBx框),但这似乎不对
我正在寻找实现这一目标的最佳方法的建议。没有代码显示,因为我不太确定从哪里开始。您可以使用单击事件或下拉事件来检测用户何时尝试打开组合框。然后在组合框的正下方显示一个带有较长字符串的列表框。当用户从列表框中选择一个字符串时,在组合框中设置相应的值。我想我几乎拥有了您想要的东西。一个小折衷:在编辑值时,组合框显示截断的长值。否则这应该很适合你 我的源代码是一个稍微编辑过的版本。在本例中,它们有一个可通过comboboxcolumn编辑的枚举。我的扩展现在将组合框更改为具有显示和值成员(displaymember是长文本,value member是实际的枚举值),并且当正常显示单元格时,单元格格式事件将起作用,覆盖显示 这些是主要的变化:
private static T GetAttribute<T>(Enum value)
{
T attribute = value.GetType()
.GetMember(value.ToString())[0].GetCustomAttributes(typeof(T), false)
.Cast<T>()
.SingleOrDefault();
return attribute;
}
DataGridViewComboBoxColumn CreateComboBoxWithEnums()
{
DataGridViewComboBoxColumn combo = new DataGridViewComboBoxColumn();
//combo.DataSource = Enum.GetValues(typeof(Title));
var datatable = new DataTable(); //Setup a DataTable for your ComboBox Column
datatable.Columns.Add("col1", typeof(string));
datatable.Columns.Add("col2", typeof(Title));
foreach (Title item in Enum.GetValues(typeof(Title)))
datatable.Rows.Add(GetAttribute<DescriptionAttribute>(item).Description, item);
combo.DisplayMember = "col1";
combo.ValueMember = "col2";
combo.DataSource = datatable;
combo.DropDownWidth = 200;
combo.DataPropertyName = "Title";
combo.Name = "Title";
return combo;
}
private void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
if (e.ColumnIndex == 0)//where Column1 is your combobox column
{
var val = dataGridView1[e.ColumnIndex, e.RowIndex].Value;
if (val != null)
{
e.Value = ((Title)val).ToString();
e.FormattingApplied = true;
}
}
}
public enum Title
{
[Description("This better be thy king!")]
King,
[Description("aka wanna-be-king")]
Sir
};
private static GetAttribute(枚举值)
{
T attribute=value.GetType()
.GetMember(value.ToString())[0]。GetCustomAttributes(typeof(T),false)
.Cast()
.SingleOrDefault();
返回属性;
}
DataGridViewComboBoxColumn CreateComboxWithEnums()
{
DataGridViewComboBoxColumn组合=新建DataGridViewComboxColumn();
//combo.DataSource=Enum.GetValues(typeof(Title));
var datatable=new datatable();//为组合框列设置一个datatable
datatable.Columns.Add(“col1”,typeof(string));
datatable.Columns.Add(“col2”,typeof(Title));
foreach(Enum.GetValues中的标题项(typeof(Title)))
datatable.Rows.Add(GetAttribute(item).Description,item);
combo.DisplayMember=“col1”;
combo.ValueMember=“col2”;
combo.DataSource=datatable;
combo.DropDownWidth=200;
combo.DataPropertyName=“Title”;
combo.Name=“Title”;
返回组合;
}
私有void dataGridView1_CellFormatting(对象发送方,DataGridViewCellFormattingEventArgs e)
{
if(e.ColumnIndex==0)//其中Column1是您的组合框列
{
var val=dataGridView1[e.ColumnIndex,e.RowIndex]。值;
如果(val!=null)
{
e、 Value=((Title)val).ToString();
e、 FormattingApplied=true;
}
}
}
公共枚举标题
{
[描述(“这最好是你的国王!”)
国王,
[描述(“aka想成为国王”)]
先生
};
完整代码:您需要更改事件下拉列表和下拉关闭列表中组合框的DisplayMember 在事件下拉列表中,您需要将DisplayMember更改为您的长名称。我发现,更改DisplayMember会重置SelectedIndex,因此您需要保存它,然后在更改显示后重置它
int i = comboBox1.SelectedIndex;
comboBox1.DisplayMember = "LongNm";
comboBox1.SelectedIndex = i;
您需要使用DropDownClosed事件和短名称重复此过程,以返回关闭的显示
int i = comboBox1.SelectedIndex;
comboBox1.DisplayMember = "ShortNm";
comboBox1.SelectedIndex = i;
我遇到的最后一个问题是更改组合框下拉列表的宽度。我找到了这样做的代码。
我的最终代码如下所示:
public partial class Form1 : Form
{
List<ComboData> data;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
data = new List<ComboData>();
data.Add(new ComboData(1, "BigBox", "Boxes larger than 6x6"));
data.Add(new ComboData(2, "SmBox", "Boxes small than 6x6"));
data.Add(new ComboData(3, "BirBrl", "Barrel 55 Gallons"));
data.Add(new ComboData(4, "smBrl", "Barrel less than 55 gallons"));
comboBox1.DataSource = data;
comboBox1.DisplayMember = "ShortNm";
}
private void comboBox1_DropDown(object sender, EventArgs e)
{
int i = comboBox1.SelectedIndex;
comboBox1.DisplayMember = "LongNm";
comboBox1.SelectedIndex = i;
ComboBox senderComboBox = (ComboBox)sender;
int width = senderComboBox.DropDownWidth;
Graphics g = senderComboBox.CreateGraphics();
Font font = senderComboBox.Font;
int vertScrollBarWidth =
(senderComboBox.Items.Count > senderComboBox.MaxDropDownItems)
? SystemInformation.VerticalScrollBarWidth : 0;
int newWidth;
foreach (ComboData s in ((ComboBox)sender).Items)
{
newWidth = (int)g.MeasureString(s.LongNm, font).Width
+ vertScrollBarWidth;
if (width < newWidth)
{
width = newWidth;
}
}
senderComboBox.DropDownWidth = width;
}
private void comboBox1_DropDownClosed(object sender, EventArgs e)
{
int i = comboBox1.SelectedIndex;
comboBox1.DisplayMember = "ShortNm";
comboBox1.SelectedIndex = i;
}
}
public class ComboData
{
public int Code;
public string ShortNm
{
get;
set;
}
public string LongNm
{
get;
set;
}
public ComboData(int c, string s, string l)
{
Code = c;
ShortNm = s;
LongNm = l;
}
}
公共部分类表单1:表单
{
列出数据;
公共表格1()
{
初始化组件();
}
私有void Form1\u加载(对象发送方、事件参数e)
{
数据=新列表();
添加(新的组合数据(1,“大盒子”,“大于6x6的盒子”);
添加(新的组合数据(2,“SmBox”,“小于6x6的框”);
数据。添加(新的组合数据(3,“比尔”、“桶55加仑”);
数据。添加(新组合数据(4,“smBrl”,“桶小于55加仑”);
comboBox1.DataSource=数据;
comboBox1.DisplayMember=“ShortNm”;
}
private void comboBox1下拉列表(对象发送方,事件参数e)
{
int i=组合框1.SelectedIndex;
comboBox1.DisplayMember=“LongNm”;
comboBox1.SelectedIndex=i;
组合框发送者组合框=(组合框)发送者;
int width=senderComboBox.DropDownWidth;
Graphics g=senderComboBox.CreateGraphics();
Font=senderComboBox.Font;
整数垂直滚动条宽度=
(senderComboBox.Items.Count>senderComboBox.MaxDropDownItems)
?SystemInformation.VerticalScrollBarWidth:0;
int newWidth;
foreach((组合框)sender.Items中的组合数据)
{
newWidth=(int)g.MeasureString(s.LongNm,font).Width
+垂直宽度;
如果(宽度<新宽度)
{
宽度=新宽度;
}
}
senderComboBox.DropDownWidth=宽度;
}
私有void comboBox1\u DropDownClosed(对象发送方,事件参数e)
{
int i=组合框1.SelectedIndex;
comboBox1.DisplayMember=“ShortNm”;
comboBox1.SelectedIndex=i;
}
}
公共类组合数据
{
公共整数码;
公共字符串缩写
{
得到;
设置
}
公共字符串长度
{
得到;
设置
}
公共组合数据(int c、字符串s、字符串l)
{
代码=c;
短nm=s;
瞧