using System; using System.Drawing; using System.Linq; using System.Windows.Forms; using TradeIdeas.TIProData; namespace TradeIdeas.TIProGUI { public partial class SymbolLookupTextBox : SymbolLookupB { public float FontSize { set { if (value > 0) txtSymbol.Font = new Font("Microsoft Sans Serif", value, FontStyle.Regular); } } private string Placeholder { get; set; } public event EventHandler OnKeyup; public event EventHandler OnLostFocusOrEsc; /// /// This collection is for special characters that can be pressed /// over the lookup symbol list /// private char[] _allowedSpecialChars = { '.', '-' }; /// /// This user control is used to search for symbols and company names via a web service call. /// The control features auto-complete functionality. /// public SymbolLookupTextBox() : base() { InitializeComponent(); txtSymbol.AutoSize = false; // suppress right click menu txtSymbol.ContextMenu = new ContextMenu(); // set up event handers for combobox txtSymbol.GotFocus += txtSymbol_GotFocus; txtSymbol.LostFocus += txtSymbol_LostFocus; } /// /// Unsubscribe to events. Call this for cleanup. /// public override void UnsubscribeEvents() { // delete event handers for textBox txtSymbol.GotFocus -= txtSymbol_GotFocus; txtSymbol.LostFocus -= txtSymbol_LostFocus; base.UnsubscribeEvents(); } /// /// Get/Set the font for the textbox/combobox. /// public new Font TextBoxFont { get => txtSymbol.Font; set => txtSymbol.Font = value; } /// /// Get the height of the textbox/combobox. /// public new int TextBoxHeight => txtSymbol.Height; /// /// Get the width of the textbox/combobox. /// public new int TextBoxWidth => txtSymbol.Width; /// /// Get/Set the text alignment for the textbox. /// public HorizontalAlignment TextAlign { get => txtSymbol.TextAlign; set => txtSymbol.TextAlign = value; } /// /// Set whether or not the symbol is valid. This will set the background color of the control /// /// Valid symbol. public override void SetValidSymbol(bool valid) { txtSymbol.BackColor = valid ? Color.White : Color.FromArgb(249, 167, 175); } /// /// Automatically sets the height of the control based on the font size of the textbox/combox /// public override void AutoSetHeight() { Height = txtSymbol.PreferredHeight; } /// /// Set the focus to the text box control. /// public override void SetTextBoxFocus() { txtSymbol.Focus(); txtSymbol.SelectionStart = txtSymbol.Text.Length; txtSymbol.SelectionLength = 0; } public void SetTextBoxPlaceholder(string placeholder) { this.Placeholder = placeholder; this.AddPlaceholder(); } protected override void SetControlSymbol(string newSymbol) { if (!string.IsNullOrEmpty(this.Placeholder)) { txtSymbol.Text = string.Empty; txtSymbol.ForeColor = Color.Black; } txtSymbol.Text = newSymbol; } /// /// Gets the symbol in the textbox/combobox. /// public override string GetSymbol() { if (!string.IsNullOrEmpty(this.Placeholder) && this.Placeholder.EqualsIgnoreCase(txtSymbol.Text)) { return string.Empty; } return txtSymbol.Text; } /// /// Set the symbol in the textbox/combobox. Value is truncated at first space. /// /// The string containing the symbol and company name. /// If true, symbolSelected event will be called public override void SetSymbol(string symbol, bool update = false, bool showLookup = false) { if (!string.IsNullOrEmpty(this.Placeholder) && string.IsNullOrEmpty(symbol)) { this.txtSymbol.Text = symbol; this.AddPlaceholder(); return; } base.SetSymbol(symbol, update, showLookup); } private void txtSymbol_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e) { if (e.KeyData == Keys.Tab) e.IsInputKey = true; } private void txtSymbol_KeyPress(object sender, KeyPressEventArgs e) { if (e.KeyChar >= 'a' && e.KeyChar <= 'z') { e.KeyChar -= (char)32; } } private void txtSymbol_KeyDown(object sender, KeyEventArgs e) { if (e.KeyCode == Keys.Enter || e.KeyCode == Keys.Tab) { _showLookup = false; timerKeystroke.Stop(); // call symbol selected event CallSymbolSelectedEvent(((TextBox)sender).Text); if (_autoCompleteShown) HideAutoComplete(false); txtSymbol.SelectionStart = 0; txtSymbol.SelectionLength = txtSymbol.Text.Length; if (e.KeyCode == Keys.Tab && this.Parent != null) this.Parent.SelectNextControl((Control)sender, true, true, true, true); } else if (e.KeyCode == Keys.Escape) { if (this.OnLostFocusOrEsc != null) { _showLookup = false; timerKeystroke.Stop(); if (_autoCompleteShown) { HideAutoComplete(false); } this.OnLostFocusOrEsc(sender, e); } } } private void txtSymbol_KeyUp(object sender, KeyEventArgs e) { if (this.OnKeyup != null) { this.OnKeyup(this, new EventArgs()); } } private void AddPlaceholder() { if (string.IsNullOrEmpty(this.Placeholder) || !string.IsNullOrEmpty(txtSymbol.Text)) { return; } txtSymbol.Text = this.Placeholder; txtSymbol.ForeColor = Color.Gray; } private void RemovePlaceholder() { if (string.IsNullOrEmpty(this.Placeholder)) { return; } if (this.Placeholder.EqualsIgnoreCase(txtSymbol.Text)) { txtSymbol.Text = string.Empty; txtSymbol.ForeColor = Color.Black; } } protected override void ShowPopup() { if (!txtSymbol.IsDisposed) // sometimes the textbox control is disposed here _popup.Show(txtSymbol, -2, txtSymbol.Height - 2); } private void txtSymbol_GotFocus(object sender, EventArgs e) { if (_autoCompleteShown) _lstSymbolLookup.ClearSelected(); RemovePlaceholder(); } private void txtSymbol_TextChanged(object sender, EventArgs e) { if (this.Placeholder.HasValue() && this.Placeholder.EqualsIgnoreCase(txtSymbol.Text)) { return; } //Invalidate Ok button in Config Window when the text if empty if (txtSymbol.Text.Length == 0) CallSymbolTextValidatedEvent(false); if (_dontUpdateLookup) return; // set backcolor to white if it's not if (txtSymbol.BackColor != Color.White) txtSymbol.BackColor = Color.White; // search for text if (txtSymbol.Text.Length > 0) { timerKeystroke.Stop(); _showLookup = true; timerKeystroke.Start(); } else if (_autoCompleteShown) { _showLookup = false; timerKeystroke.Stop(); HideAutoComplete(true); } else { _showLookup = false; timerKeystroke.Stop(); } } protected override void autoCompleteListBox_DrawItem(object sender, DrawItemEventArgs e, string searchText) { base.autoCompleteListBox_DrawItem(sender, e, txtSymbol.Text); } private void txtSymbol_LostFocus(object sender, EventArgs e) { timerKeystroke.Stop(); AddPlaceholder(); if (this.OnLostFocusOrEsc != null && !_autoCompleteShown) { this.OnLostFocusOrEsc(sender, e); } _showLookup = false; } protected override void lstSymbolLookup_KeyPress(object sender, KeyPressEventArgs e) { //Debug.WriteLine("key down " + e.KeyChar); if (Char.IsLetterOrDigit(e.KeyChar) || e.KeyChar == (char)32 || _allowedSpecialChars.Contains(e.KeyChar)) // character, digit, space, or allowed special character { txtSymbol.Text += Char.ToUpper(e.KeyChar); } else if (e.KeyChar == (char)8) // backspace { if (txtSymbol.Text.Length > 0) txtSymbol.Text = txtSymbol.Text.Substring(0, txtSymbol.Text.Length - 1); } base.lstSymbolLookup_KeyPress(sender, e); } protected override void timerKeystroke_Tick(object sender, EventArgs e, string searchText) { base.timerKeystroke_Tick(sender, e, txtSymbol.Text); } } }