自定义控件 - 如何在组合框上绘制文本框

Custom Control - How to Draw Textbox on combobox

我正在开发 Win Form 应用程序 在我的 UI 中,我必须制作 ComboBox 一开始应该只是下拉菜单,但在选择任何项目后,它应该是部分可编辑的。

选项就像

物品价值 - 10

物品价值 - 20

物品价值 - 30 等等

现在,如果选择 Item Value - 20,数字 20 应该是可编辑的(当然是 20-29)

但这里的编辑应该只允许更改数值,而不是文本部分。 并且也只应选择数字部分以使其更加用户友好。

如果 ComboBox 中可能有一些内部属性可以这样做(我猜不会是这种情况),那将是直截了当的方式。

否则,我正在考虑 TextBox drawn/placed 在 ComboCox 上准确。

在这种方法中,我不清楚如何将 TextBox 放置得如此准确,以至于 我的自定义用户控件看起来像一个单元并且它不与 "text" 部分重叠组合框 ?

我不认为组合框控件旨在以这种方式使用,因为如果您和用户必须输入数据,一个简单的验证文本框似乎是更好的控件。当然,您可以简单地将所需的所有数字添加到组合框中,但用户必须滚动到他们想要的数字。如果这个列表很大,那么它就不会非常用户友好。用户在组合框中键入内容的问题在于用户完成键入后要做什么。即使有建议,当用户在组合框中完成输入时,在用户按下 Enter 键之前什么也不会发生。

如果用户键入的内容与列表中的一项匹配,然后按下 Enter 键,组合框 SelectedIndexChanged 事件将被触发。但是,如果用户键入当前不在项目列表中的内容并按下 Enter 键,则不会触发 SelectedIndexChanged 事件。

使用组合框 KeyDown 事件,您可以在用户按下组合框中的回车键时捕获“EnterKey”,因为这是用户无论如何都会做的事情 select一个现有的项目。因此,当用户键入列表中已存在的内容并按下 Enter 键时,SelectedIndexChangedKeyDown 事件都会按该顺序触发。如果用户键入的内容不在项目列表中,则只会触发 KeyDown 事件。

使用 KeyDown 事件检查 selected 值是什么。如果用户键入的项目在项目列表中,那么我们可以忽略这些,因为它们在之前调用 SelectedIndexChanged 时已处理。当用户键入新内容时,显然您可能需要检查值的范围,然后只需使用用户输入调用您的方法。

同样,这看起来很老套,恕我直言,经过验证的文本框对您来说更容易,对用户来说也很简单,尤其是当他们无论如何都必须输入时。

List<string> comboData;
public Form1() {
  InitializeComponent();
  comboData = new List<string>();
  for (int i = 1; i < 100; i++) {
    comboData.Add(i.ToString());
  }
  comboBox1.DataSource = comboData;
}
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e) {
  MessageBox.Show("selection changed  " + comboBox1.Text);
}
private void comboBox1_KeyDown(object sender, KeyEventArgs e) {
  if (e.KeyCode == Keys.Enter) {
    if (comboData.Contains(comboBox1.Text.ToString())) {
      MessageBox.Show("User entered existing data: " + comboBox1.Text);
      // selection changed event has already handled this, however
      // if the user just pressed "enter" previously
      // then selection changed event wont get fired because the selection did not change
    }
    else {
      MessageBox.Show("User entered NEW data: " + comboBox1.Text);
      // we have data that is NOT currently in the list
      // so selection changed WONT get fired
      // need to call your method with user typed value
    }
  }
}
// make user user only enters numbers
private void comboBox1_KeyPress(object sender, KeyPressEventArgs e) {
  if (!Char.IsNumber(e.KeyChar)) {
    e.Handled = true;
  }
}

注意:我不知道你的组合项目列表到底包含什么。如果项目中有“Item Value –”之类的文本……这似乎是不必要的。在上面的代码中,我只是使用了所需的信息,即……组合框项目列表中的数字。我还使用按键事件来过滤掉不需要的字母字符。

希望对您有所帮助。