ListBox.cs 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. using System.Windows.Input;
  2. namespace System.Windows.Forms
  3. {
  4. public partial class ListBox : ListControl
  5. {
  6. public const int NoMatches = -1;
  7. protected new CustomControls.OwnerDrawListBox control { get; }
  8. public SelectedObjectCollection SelectedItems { get; }
  9. private SelectedIndexCollection selectedIndices;
  10. public SelectedIndexCollection SelectedIndices
  11. {
  12. get
  13. {
  14. if (selectedIndices == null)
  15. BuildSelectedIndices();
  16. return selectedIndices;
  17. }
  18. }
  19. public int ItemHeight
  20. {
  21. get => (int)(control.ItemHeight * DpiScale);
  22. set => control.ItemHeight = (int)(value / DpiScale);
  23. }
  24. private DrawMode drawMode;
  25. public DrawMode DrawMode
  26. {
  27. get => drawMode;
  28. set
  29. {
  30. drawMode = value;
  31. control.OwnerDraw = value != DrawMode.Normal;
  32. }
  33. }
  34. private SelectionMode selectionMode;
  35. public SelectionMode SelectionMode
  36. {
  37. get => selectionMode;
  38. set
  39. {
  40. selectionMode = value;
  41. control.SelectionMode = value switch
  42. {
  43. SelectionMode.MultiSimple => Windows.Controls.SelectionMode.Multiple,
  44. SelectionMode.MultiExtended => Windows.Controls.SelectionMode.Extended,
  45. _ => Windows.Controls.SelectionMode.Single
  46. };
  47. }
  48. }
  49. public int TopIndex
  50. {
  51. get => SelectedIndex;
  52. set
  53. {
  54. if (value != -1)
  55. control.ScrollIntoView(Items[value]);
  56. }
  57. }
  58. private bool horizontalScrollbar;
  59. public bool HorizontalScrollbar
  60. {
  61. get => horizontalScrollbar;
  62. set
  63. {
  64. horizontalScrollbar = value;
  65. control.SetValue(Windows.Controls.ScrollViewer.HorizontalScrollBarVisibilityProperty, value ? Windows.Controls.ScrollBarVisibility.Visible : Windows.Controls.ScrollBarVisibility.Hidden);
  66. }
  67. }
  68. // these 3 are ignored
  69. public bool UseTabStops { get; set; }
  70. public int ColumnWidth { get; set; }
  71. public bool MultiColumn { get; set; }
  72. public event DrawItemEventHandler DrawItem;
  73. public event MeasureItemEventHandler MeasureItem;
  74. private void ListBox_MouseDown(object sender, MouseButtonEventArgs e)
  75. {
  76. var element = control.InputHitTest(e.GetPosition(control));
  77. if (element is FrameworkElement itm && itm.DataContext != null)
  78. {
  79. // fire event when clicked on the item (otherwise it will be skipped)
  80. OnMouseDown(Helper.GetMouseEventArgs(control, e));
  81. }
  82. }
  83. private void BuildSelectedIndices()
  84. {
  85. selectedIndices = new SelectedIndexCollection(this);
  86. for (int i = 0; i < control.SelectedItems.Count; i++)
  87. {
  88. var item = control.SelectedItems[i];
  89. selectedIndices.AddInternal(control.Items.IndexOf(item));
  90. }
  91. }
  92. protected virtual void OnDrawItem(DrawItemEventArgs e) => DrawItem?.Invoke(this, e);
  93. protected virtual void OnMeasureItem(MeasureItemEventArgs e) => MeasureItem?.Invoke(this, e);
  94. protected override void OnSelectionChanged(EventArgs e)
  95. {
  96. base.OnSelectionChanged(e);
  97. control.ScrollIntoView(SelectedItem);
  98. selectedIndices = null;
  99. }
  100. public void ClearSelected()
  101. {
  102. control.SelectedItems.Clear();
  103. }
  104. public void SetSelected(int index, bool selected)
  105. {
  106. var item = Items[index];
  107. if (selected)
  108. control.SelectedItems.Add(item);
  109. else
  110. control.SelectedItems.Remove(item);
  111. }
  112. public int IndexFromPoint(int x, int y)
  113. {
  114. object item = null;
  115. var element = control.InputHitTest(new Point(x / DpiScale, y / DpiScale));
  116. if (element is FrameworkElement itm)
  117. {
  118. item = itm.DataContext;
  119. }
  120. return item == null ? -1 : Items.IndexOf(item);
  121. }
  122. public int IndexFromPoint(Drawing.Point pos) => IndexFromPoint(pos.X, pos.Y);
  123. public ListBox()
  124. {
  125. control = new();
  126. SetControl(control);
  127. SelectedItems = new SelectedObjectCollection(control.SelectedItems);
  128. control.DrawItem += (sender, e) => OnDrawItem(e);
  129. control.MeasureItem += (sender, e) => OnMeasureItem(e);
  130. // use this instead of PreviewMouseDown! do not allow unhandled event to bubble/tunnel/whatever
  131. control.AddHandler(UIElement.MouseDownEvent, new MouseButtonEventHandler(ListBox_MouseDown), true);
  132. // std Control code does not work for these events
  133. control.MouseDoubleClick += (s, e) =>
  134. {
  135. OnMouseDoubleClick(Helper.GetMouseEventArgs(control, e));
  136. OnDoubleClick(EventArgs.Empty);
  137. };
  138. HorizontalScrollbar = false;
  139. Width = 120;
  140. Height = 96;
  141. }
  142. }
  143. }