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

时间:2017-01-16 13:56:58

标签: c# user-interface combobox textbox custom-controls

我正在开发Win Form Application 在我的用户界面中,我必须首先制作ComboBox,但最初应该是下拉列表,但在选择任何项目后,它应该是部分可编辑的。

E.G。 选项就像,

物品价值 - 10

物品价值 - 20

物品价值 - 30等。

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

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

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

否则,我正在考虑准确地TextBox ComboCox TextBox

在这种方法中,我不清楚如何准确地 class Executor { public delegate void CalculationCompletEventHandler(int score); public event CalculationCompletEventHandler CalculationCompleted; public void Start() { CalculationCompleted += OnCalculationCompleted; Plus plus = new Plus(1, 2, CalculationCompleted); Minus minus = new Minus(5, 2, CalculationCompleted); Multi multi = new Multi(5, 2, CalculationCompleted); ... ... They will work async... } private void OnCalculationCompleted(int score) { Console.WriteLine("OnCalculationCompleted , score=" + score); } } class Plus { private Executor.CalculationCompletEventHandler _calculationCompletEventHandler; private int a; private int b; public Plus(int a, int b,Executor.CalculationCompletEventHandler calculationCompletEventHandler) { this.a = a; this.b = b; _calculationCompletEventHandler = calculationCompletEventHandler; } public void Calculate() { _calculationCompletEventHandler?.Invoke(a+b); } } class Program { static void Main(string[] args) { Executor executor = new Executor(); executor.Start(); // async action executor.CalculationCompleted += ExecutorOnCalculationCompleted; ... } // This method doesn't get invoked when the class inside Executor fire the event. private static void ExecutorOnCalculationCompleted(int score) { Console.WriteLine("ExecutorOnCalculationCompleted , score=" + score); } } 使我的自定义用户控件看起来像单个单元并且它不与组合框的“文本”部分重叠

1 个答案:

答案 0 :(得分:0)

我认为组合框控件并不打算以这种方式使用,因为如果一个简单的验证文本框必须输入数据,它对您和用户来说似乎更好。当然,您只需将所需的所有数字添加到组合框中,但用户必须滚动到他们想要的数字。如果此列表很大,那么它将不是非常用户友好。用户在组合框中键入内容的问题是用户完成键入时要执行的操作。即使有建议,当用户完成在组合框中输入内容时,在用户按下Enter键之前不会发生任何事情。

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

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

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

再次,这似乎是hacky和恕我直言,一个经过验证的文本框对你来说会更容易,对用户来说也很简单,特别是如果他们不得不输入它。

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;
  }
}

注意:我无法确定您的组合项目列表包含的内容。如果“项目值 - ”等项目中有文字......这似乎没必要。在上面的代码中,我只使用了所需的信息,即组合框项目列表中的数字。我还使用了按键事件来过滤掉不需要的字母字符。

希望这会有所帮助。