我正在创建一个扩展CheckedListBox的简单类,它只在选中项时右侧添加一个小文本框。我的问题是找到一个将盒子放在正确位置的好方法。
我最初虽然可以使用Controls.Find()和ItemCheckEventArgs索引来获取相关复选框的坐标,然后从那里移动到列的右边缘。但是,这不起作用,并且通过CheckedListBox类的简要介绍似乎表明它实际上不包含任何CheckBox控件,而只是绘制它们的图像。
然后我想出了以下方法:
void CreateAmountBox(int index)
{
int itemsPerCol = Height/ItemHeight;
int x = GetColumn(index, itemsPerCol)*ColumnWidth - boxWidth;
int y = (index % itemsPerCol)*ItemHeight - offset;
System.Windows.Forms.TextBox NewAmountTextBox = new System.Windows.Forms.TextBox();
NewAmountTextBox.Location = new System.Drawing.Point(x, y);
NewAmountTextBox.Name = Items[index] + "Amount";
NewAmountTextBox.Size = new System.Drawing.Size(20, boxWidth);
Controls.Add(NewAmountTextBox);
}
其中GetColumn(...)返回给定索引的列(来自CheckEventArgs)。这很有效,但感觉就像一个黑客,并且不太可读。
我想到的另外两个想法:
1)我可以在开始时创建所有TextBox,只需隐藏它们直到需要它们。这些控件都是在程序的其余部分动态创建的,但是我并不希望这些控件成为奇怪的例外。这也意味着在添加或删除项目时需要添加更多功能。
2)我可以使用鼠标位置,如果通过键盘输入,这当然不会起作用。我不会预料到它会如此,但最好不要留下这种可能性。
通过一些谷歌搜索,我发现可能这样做的唯一另一种方法是使用ListBoxItem和TranslatePoint方法,但我还没有得到它的工作,我不确定它是否甚至可以使用CheckedListBox而不是ListBox。
那么,是否有一种简单的方法可以找到我不知道的已检查项目的x和y?或者我仅限于将上面的x和y声明提取到方法中并将其留在那里?
答案 0 :(得分:3)
您可以使用GetItemRectangle函数来实现:
void checkedListBox1_ItemCheck(object sender, ItemCheckEventArgs e) {
Rectangle r = checkedListBox1.GetItemRectangle(e.Index);
TextBox newAmountTextBox = new TextBox();
newAmountTextBox.Location = new Point(r.Left, r.Top);
//...
}