|
5 | 5 | using System.Windows.Controls.Primitives; |
6 | 6 | using System.Windows.Input; |
7 | 7 | using iNKORE.UI.WPF.Converters; |
| 8 | +using iNKORE.UI.WPF.Modern.Controls.Primitives; |
8 | 9 |
|
9 | 10 | namespace iNKORE.UI.WPF.Modern.Controls.Helpers |
10 | 11 | { |
@@ -92,56 +93,38 @@ private static void OnDropDownOpened(object sender, object args) |
92 | 93 |
|
93 | 94 | private static void AlignSelectedContainer(ComboBox comboBox, Popup popup) |
94 | 95 | { |
95 | | - if (comboBox.IsEditable) |
| 96 | + if (comboBox.IsEditable || comboBox.ItemContainerGenerator.Items.Count < 1) |
96 | 97 | { |
97 | 98 | popup.VerticalOffset = 0; |
98 | 99 | return; |
99 | 100 | } |
100 | 101 |
|
101 | | - if (GetToAlignContainer(comboBox) is not { } itemContainer || |
102 | | - itemContainer.TranslatePoint(new Point(0, -itemContainer.ActualHeight + itemContainer.Padding.Top + comboBox.Padding.Top), |
103 | | - comboBox) is not { Y: not 0 } itemTop) |
104 | | - { |
105 | | - return; |
106 | | - } |
107 | | - |
108 | | - while (itemTop.Y is not 0) |
| 102 | + var mockContainer = (comboBox.ItemContainerGenerator.ContainerFromIndex(0) as ComboBoxItem)!; |
| 103 | + var scrollViewer = GetTemplateChild<ScrollViewer>("ScrollViewer", comboBox); |
| 104 | + |
| 105 | + var toSelectIndex = comboBox.SelectedIndex; |
| 106 | + if (toSelectIndex < 0) |
109 | 107 | { |
110 | | - var preY = itemTop.Y; |
111 | | - popup.VerticalOffset -= preY; |
112 | | - itemTop = itemContainer.TranslatePoint(new Point(0, -itemContainer.ActualHeight + comboBox.Padding.Top), |
113 | | - comboBox); |
114 | | - |
115 | | - var postY = itemTop.Y; |
116 | | - |
117 | | - if (postY >= preY) |
118 | | - { |
119 | | - //if this loop didn't bring the popup top closer, then this mean the popup couldn't position itself. |
120 | | - break; |
121 | | - } |
| 108 | + toSelectIndex = (int)Math.Ceiling(comboBox.Items.Count / 2.0); |
| 109 | + TryHighlightingFirstItem(comboBox); |
122 | 110 | } |
123 | | - |
124 | | - if (itemContainer.ActualHeight - comboBox.ActualHeight > 0) |
| 111 | + else if (mockContainer.ActualHeight * comboBox.Items.Count > comboBox.MaxDropDownHeight) |
125 | 112 | { |
126 | | - popup.VerticalOffset -= comboBox.ActualHeight; |
| 113 | + toSelectIndex = 0; |
127 | 114 | } |
128 | | - } |
| 115 | + |
| 116 | + var paddingBorder = (scrollViewer.Parent as Border)!; |
129 | 117 |
|
130 | | - private static ComboBoxItem GetToAlignContainer(ComboBox comboBox) |
131 | | - { |
132 | | - DependencyObject container; |
133 | | - if (comboBox.SelectedItem is null) |
| 118 | + if (IsPopupOpenDown(comboBox, popup.VerticalOffset)) |
134 | 119 | { |
135 | | - container = comboBox.ItemContainerGenerator.ContainerFromIndex( |
136 | | - (int)Math.Ceiling(comboBox.Items.Count / 2.0)); |
137 | | - TryHighlightingFirstItem(comboBox); |
| 120 | + popup.VerticalOffset = -mockContainer.ActualHeight * (toSelectIndex + 1) - paddingBorder.Padding.Top; |
138 | 121 | } |
139 | 122 | else |
140 | 123 | { |
141 | | - container = comboBox.ItemContainerGenerator.ContainerFromItem(comboBox.SelectedItem); |
| 124 | + popup.VerticalOffset = |
| 125 | + mockContainer.ActualHeight * (Math.Min((int)(comboBox.MaxDropDownHeight / mockContainer.ActualHeight), comboBox.Items.Count) - toSelectIndex) + |
| 126 | + paddingBorder.Padding.Bottom; |
142 | 127 | } |
143 | | - |
144 | | - return container as ComboBoxItem; |
145 | 128 | } |
146 | 129 |
|
147 | 130 | private static void TryHighlightingFirstItem(ComboBox comboBox) |
@@ -221,7 +204,7 @@ private static bool IsPopupOpenDown(ComboBox comboBox, double popupVerticalOffse |
221 | 204 |
|
222 | 205 | var popupTopPoint = popupBorder.TranslatePoint(new Point(0, 0), textBox); |
223 | 206 |
|
224 | | - return popupTopPoint.Y + popupVerticalOffset > 0; |
| 207 | + return popupTopPoint.Y > popupVerticalOffset; |
225 | 208 | } |
226 | 209 |
|
227 | 210 | private static object ResourceLookup(Control control, object key) |
|
0 commit comments