有没有一种简单的方法来获取checkedlistbox中特定项的坐标?

时间:2014-07-02 19:03:39

标签: c# winforms refactoring coordinates checkedlistbox

我正在创建一个扩展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声明提取到方法中并将其留在那里?

1 个答案:

答案 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);
  //...
}