OwnerDrawComboBox.cs 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. using System;
  2. using System.ComponentModel;
  3. using System.Windows;
  4. using System.Windows.Controls;
  5. using System.Windows.Forms;
  6. using System.Windows.Media;
  7. namespace CustomControls
  8. {
  9. [DesignTimeVisible(false)]
  10. public class OwnerDrawComboBox : System.Windows.Controls.ComboBox
  11. {
  12. private bool isOwnerDraw;
  13. private bool isDropDownList;
  14. private System.Drawing.Graphics measureGraphics;
  15. private System.Drawing.Graphics MeasureGraphics => measureGraphics ??= System.Drawing.Graphics.FromHwnd(IntPtr.Zero);
  16. public string ComboText
  17. {
  18. get { return (string)GetValue(ComboTextProperty); }
  19. set { SetValue(ComboTextProperty, value); }
  20. }
  21. public static readonly DependencyProperty ComboTextProperty =
  22. DependencyProperty.Register("ComboText", typeof(string), typeof(OwnerDrawComboBox), new PropertyMetadata(""));
  23. public double DropDownWidth
  24. {
  25. get { return (double)GetValue(DropDownWidthProperty); }
  26. set { SetValue(DropDownWidthProperty, value); }
  27. }
  28. public static readonly DependencyProperty DropDownWidthProperty =
  29. DependencyProperty.Register("DropDownWidth", typeof(double), typeof(OwnerDrawComboBox), new PropertyMetadata(0.0));
  30. public double ItemHeight
  31. {
  32. get { return (double)GetValue(ItemHeightProperty); }
  33. set { SetValue(ItemHeightProperty, value); }
  34. }
  35. public readonly static DependencyProperty ItemHeightProperty = DependencyProperty.Register(
  36. "ItemHeight", typeof(double), typeof(OwnerDrawComboBox), new UIPropertyMetadata(15.0));
  37. public event EventHandler TextChanged;
  38. public event DrawItemEventHandler DrawItem;
  39. public event MeasureItemEventHandler MeasureItem;
  40. internal void TextBox_TextChanged(object sender, TextChangedEventArgs e)
  41. {
  42. OnTextChanged(e);
  43. }
  44. internal void TextBox_PreviewMouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
  45. {
  46. var tb = (sender as System.Windows.Controls.TextBox);
  47. if (!tb.IsKeyboardFocusWithin)
  48. {
  49. e.Handled = true;
  50. tb.Focus();
  51. }
  52. }
  53. internal void TextBox_GotKeyboardFocus(object sender, System.Windows.Input.KeyboardFocusChangedEventArgs e)
  54. {
  55. (sender as System.Windows.Controls.TextBox).SelectAll();
  56. }
  57. internal void OnTextChanged(EventArgs e) => TextChanged?.Invoke(this, e);
  58. internal void OnDrawItem(object sender, DrawItemEventArgs args) => DrawItem?.Invoke(this, args);
  59. internal Size OnMeasureItem(int index, Size size)
  60. {
  61. var scale = Helper.GetDpiScale(this);
  62. var args = new MeasureItemEventArgs(MeasureGraphics, index, (int)(ItemHeight * scale));
  63. MeasureItem?.Invoke(this, args);
  64. size.Height = index >= 0 ? (args.ItemHeight / scale) : ItemHeight;
  65. return size;
  66. }
  67. public void SetOwnerDraw()
  68. {
  69. isOwnerDraw = true;
  70. if (isDropDownList)
  71. Template = (ControlTemplate)Resources["ComboBoxTemplate"];
  72. else
  73. Template = (ControlTemplate)Resources["ComboBoxEditableTemplate"];
  74. ItemContainerStyle = (Style)Resources["ItemContainerStyle1"];
  75. ItemTemplate = (DataTemplate)Resources["ItemTemplate1"];
  76. }
  77. public void SetDropDownList()
  78. {
  79. isDropDownList = true;
  80. Template = (ControlTemplate)Resources["ComboBoxTemplate"];
  81. if (isOwnerDraw)
  82. ItemTemplate = (DataTemplate)Resources["ItemTemplate1"];
  83. else
  84. ItemTemplate = (DataTemplate)Resources["ItemTemplate"];
  85. }
  86. }
  87. [DesignTimeVisible(false)]
  88. public class OwnerDrawComboBoxItem : OwnerDrawItem
  89. {
  90. protected override void OnRender(DrawingContext drawingContext)
  91. {
  92. OwnerDrawComboBox comboBox = null;
  93. int index = 0;
  94. bool isSelected = false;
  95. bool isMouseOver = false;
  96. bool comboboxEdit = false;
  97. var listItem = WpfHelper.FindAncestor<System.Windows.Controls.ComboBoxItem>(this);
  98. if (listItem != null)
  99. {
  100. comboBox = ItemsControl.ItemsControlFromItemContainer(listItem) as OwnerDrawComboBox;
  101. index = comboBox.ItemContainerGenerator.IndexFromContainer(listItem);
  102. isSelected = listItem.IsSelected;
  103. isMouseOver = listItem.IsMouseOver;
  104. }
  105. else
  106. {
  107. comboBox = WpfHelper.FindAncestor<OwnerDrawComboBox>(this);
  108. index = comboBox.SelectedIndex;
  109. comboboxEdit = true;
  110. }
  111. OnDrawItem(drawingContext, index, isSelected, comboBox.IsEnabled, isMouseOver, comboboxEdit, comboBox.OnDrawItem);
  112. }
  113. protected override Size MeasureOverride(Size constraint)
  114. {
  115. OwnerDrawComboBox comboBox = null;
  116. int index = 0;
  117. var listItem = WpfHelper.FindAncestor<System.Windows.Controls.ComboBoxItem>(this);
  118. if (listItem != null)
  119. {
  120. comboBox = ItemsControl.ItemsControlFromItemContainer(listItem) as OwnerDrawComboBox;
  121. index = comboBox.ItemContainerGenerator.IndexFromContainer(listItem);
  122. }
  123. else
  124. {
  125. comboBox = WpfHelper.FindAncestor<OwnerDrawComboBox>(this);
  126. index = -1;
  127. }
  128. return comboBox.OnMeasureItem(index, base.MeasureOverride(constraint));
  129. }
  130. }
  131. }