using System; using System.ComponentModel; using System.Windows; using System.Windows.Controls; using System.Windows.Forms; using System.Windows.Media; namespace CustomControls { [DesignTimeVisible(false)] public class OwnerDrawComboBox : System.Windows.Controls.ComboBox { private bool isOwnerDraw; private bool isDropDownList; private System.Drawing.Graphics measureGraphics; private System.Drawing.Graphics MeasureGraphics => measureGraphics ??= System.Drawing.Graphics.FromHwnd(IntPtr.Zero); public string ComboText { get { return (string)GetValue(ComboTextProperty); } set { SetValue(ComboTextProperty, value); } } public static readonly DependencyProperty ComboTextProperty = DependencyProperty.Register("ComboText", typeof(string), typeof(OwnerDrawComboBox), new PropertyMetadata("")); public double DropDownWidth { get { return (double)GetValue(DropDownWidthProperty); } set { SetValue(DropDownWidthProperty, value); } } public static readonly DependencyProperty DropDownWidthProperty = DependencyProperty.Register("DropDownWidth", typeof(double), typeof(OwnerDrawComboBox), new PropertyMetadata(0.0)); public double ItemHeight { get { return (double)GetValue(ItemHeightProperty); } set { SetValue(ItemHeightProperty, value); } } public readonly static DependencyProperty ItemHeightProperty = DependencyProperty.Register( "ItemHeight", typeof(double), typeof(OwnerDrawComboBox), new UIPropertyMetadata(15.0)); public event EventHandler TextChanged; public event DrawItemEventHandler DrawItem; public event MeasureItemEventHandler MeasureItem; internal void TextBox_TextChanged(object sender, TextChangedEventArgs e) { OnTextChanged(e); } internal void TextBox_PreviewMouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e) { var tb = (sender as System.Windows.Controls.TextBox); if (!tb.IsKeyboardFocusWithin) { e.Handled = true; tb.Focus(); } } internal void TextBox_GotKeyboardFocus(object sender, System.Windows.Input.KeyboardFocusChangedEventArgs e) { (sender as System.Windows.Controls.TextBox).SelectAll(); } internal void OnTextChanged(EventArgs e) => TextChanged?.Invoke(this, e); internal void OnDrawItem(object sender, DrawItemEventArgs args) => DrawItem?.Invoke(this, args); internal Size OnMeasureItem(int index, Size size) { var scale = Helper.GetDpiScale(this); var args = new MeasureItemEventArgs(MeasureGraphics, index, (int)(ItemHeight * scale)); MeasureItem?.Invoke(this, args); size.Height = index >= 0 ? (args.ItemHeight / scale) : ItemHeight; return size; } public void SetOwnerDraw() { isOwnerDraw = true; if (isDropDownList) Template = (ControlTemplate)Resources["ComboBoxTemplate"]; else Template = (ControlTemplate)Resources["ComboBoxEditableTemplate"]; ItemContainerStyle = (Style)Resources["ItemContainerStyle1"]; ItemTemplate = (DataTemplate)Resources["ItemTemplate1"]; } public void SetDropDownList() { isDropDownList = true; Template = (ControlTemplate)Resources["ComboBoxTemplate"]; if (isOwnerDraw) ItemTemplate = (DataTemplate)Resources["ItemTemplate1"]; else ItemTemplate = (DataTemplate)Resources["ItemTemplate"]; } } [DesignTimeVisible(false)] public class OwnerDrawComboBoxItem : OwnerDrawItem { protected override void OnRender(DrawingContext drawingContext) { OwnerDrawComboBox comboBox = null; int index = 0; bool isSelected = false; bool isMouseOver = false; bool comboboxEdit = false; var listItem = WpfHelper.FindAncestor(this); if (listItem != null) { comboBox = ItemsControl.ItemsControlFromItemContainer(listItem) as OwnerDrawComboBox; index = comboBox.ItemContainerGenerator.IndexFromContainer(listItem); isSelected = listItem.IsSelected; isMouseOver = listItem.IsMouseOver; } else { comboBox = WpfHelper.FindAncestor(this); index = comboBox.SelectedIndex; comboboxEdit = true; } OnDrawItem(drawingContext, index, isSelected, comboBox.IsEnabled, isMouseOver, comboboxEdit, comboBox.OnDrawItem); } protected override Size MeasureOverride(Size constraint) { OwnerDrawComboBox comboBox = null; int index = 0; var listItem = WpfHelper.FindAncestor(this); if (listItem != null) { comboBox = ItemsControl.ItemsControlFromItemContainer(listItem) as OwnerDrawComboBox; index = comboBox.ItemContainerGenerator.IndexFromContainer(listItem); } else { comboBox = WpfHelper.FindAncestor(this); index = -1; } return comboBox.OnMeasureItem(index, base.MeasureOverride(constraint)); } } }