using CustomControls; namespace System.Windows.Forms { public class ComboBoxBase : ListControl { private CustomControls.OwnerDrawComboBox comboBox; private bool suppressSelectionChanged; public ComboBoxStyle DropDownStyle { get => comboBox.IsEditable ? ComboBoxStyle.DropDown : ComboBoxStyle.DropDownList; set { comboBox.IsEditable = value == ComboBoxStyle.DropDown; if (value == ComboBoxStyle.DropDownList) comboBox.SetDropDownList(); } } public override string Text { get => comboBox.ComboText; set { suppressSelectionChanged = true; if (comboBox.ComboText != value) { comboBox.ComboText = value; OnTextChanged(EventArgs.Empty); } comboBox.SelectedIndex = FindStringExact(value); suppressSelectionChanged = false; } } public int ItemHeight { get => (int)(comboBox.ItemHeight * DpiScale); set => comboBox.ItemHeight = (int)(value / DpiScale); } private DrawMode drawMode; public DrawMode DrawMode { get => drawMode; set { drawMode = value; if (value != DrawMode.Normal) comboBox.SetOwnerDraw(); } } public int DropDownWidth { get => (int)(comboBox.DropDownWidth * DpiScale); set => comboBox.DropDownWidth = value / DpiScale; } public int DropDownHeight { get => (int)(comboBox.MaxDropDownHeight * DpiScale); set => comboBox.MaxDropDownHeight = value / DpiScale; } public int MaxDropDownItems { get; set; } // TODO? public event DrawItemEventHandler DrawItem; public event MeasureItemEventHandler MeasureItem; public event EventHandler DropDown; public event EventHandler SelectionChangeCommitted; protected virtual void OnDrawItem(DrawItemEventArgs e) => DrawItem?.Invoke(this, e); protected virtual void OnMeasureItem(MeasureItemEventArgs e) => MeasureItem?.Invoke(this, e); protected virtual void OnDropDown(EventArgs e) => DropDown?.Invoke(this, e); protected override void OnSelectedIndexChanged(EventArgs e) { if (suppressSelectionChanged) return; // check if selected item is string: wrong behavior in FR PG object's combobox if (SelectedIndex != -1 && Items[SelectedIndex] is string) Text = Items[SelectedIndex].ToString(); // reset Text: wrong behavior in FR Relation editor if (SelectedIndex == -1 && !comboBox.IsEditable) Text = null; base.OnSelectedIndexChanged(e); // this event fires when item is selected by the user if (comboBox.IsDropDownOpen) { // suppress side effects that may happen due to the user code in SelectionChangeCommitted suppressSelectionChanged = true; SelectionChangeCommitted?.Invoke(this, e); suppressSelectionChanged = false; } } protected override void SetControlHeight(int value) { // in SWF, this is controlled by the ItemHeight } protected void SetComboBox(CustomControls.OwnerDrawComboBox comboBox) { this.comboBox = comboBox; SetControl(comboBox); comboBox.IsEditable = true; comboBox.TextChanged += (sender, e) => OnTextChanged(e); comboBox.DrawItem += (sender, e) => OnDrawItem(e); comboBox.MeasureItem += (sender, e) => OnMeasureItem(e); comboBox.DropDownOpened += (sender, e) => OnDropDown(e); } public override void Refresh() { base.Refresh(); var nullItem = comboBox.Template.FindName("nullItem", comboBox) as OwnerDrawItem; nullItem?.InvalidateVisual(); } } }