Skip to content

Commit 6a92ce0

Browse files
committed
popup can't be bottom case
1 parent e0e5743 commit 6a92ce0

File tree

3 files changed

+75
-76
lines changed

3 files changed

+75
-76
lines changed

source/iNKORE.UI.WPF.Modern/Controls/Helpers/WinUIComboBoxBehaviorHelper.cs

Lines changed: 55 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,9 @@ static WinUIComboBoxBehaviorHelper()
1717
}
1818

1919
private const string c_popupBorderName = "PopupBorder";
20-
2120
private const string c_editableTextName = "PART_EditableTextBox";
22-
23-
//private const string c_editableTextBorderName = "BorderElement";
2421
private const string c_backgroundName = "Background";
25-
2622
private const string c_highlightBackgroundName = "HighlightBackground";
27-
28-
//private const string c_controlCornerRadiusKey = "ControlCornerRadius";
2923
private const string c_overlayCornerRadiusKey = "OverlayCornerRadius";
3024

3125
/// <summary>
@@ -89,59 +83,84 @@ private static void OnDropDownOpened(object sender, object args)
8983
comboBox.Dispatcher.BeginInvoke(() =>
9084
{
9185
var popup = GetTemplateChild<Popup>("PART_Popup", comboBox);
92-
var isOpenDown = IsPopupOpenDown(comboBox, popup.VerticalOffset);
9386

94-
AlignSelectedContainer(comboBox, popup, isOpenDown);
87+
AlignSelectedContainer(comboBox, popup);
88+
var isOpenDown = IsPopupOpenDown(comboBox, popup.VerticalOffset);
9589
UpdateCornerRadius(comboBox, popup, true, isOpenDown);
9690
});
9791
}
9892

99-
private static void AlignSelectedContainer(ComboBox comboBox, Popup popup, bool isOpenDown)
93+
private static void AlignSelectedContainer(ComboBox comboBox, Popup popup)
10094
{
101-
if (!isOpenDown ||
102-
GetToAlignContainer(comboBox) is not { } itemContainer ||
103-
itemContainer.TranslatePoint(new Point(0, -itemContainer.ActualHeight + comboBox.Padding.Top),
95+
if (comboBox.IsEditable)
96+
{
97+
popup.VerticalOffset = 0;
98+
return;
99+
}
100+
101+
if (GetToAlignContainer(comboBox) is not { } itemContainer ||
102+
itemContainer.TranslatePoint(new Point(0, -itemContainer.ActualHeight + itemContainer.Padding.Top + comboBox.Padding.Top),
104103
comboBox) is not { Y: not 0 } itemTop)
105104
{
106105
return;
107106
}
108107

109-
popup.VerticalOffset -= itemTop.Y;
108+
while (itemTop.Y is not 0)
109+
{
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+
}
122+
}
110123

111124
if (itemContainer.ActualHeight - comboBox.ActualHeight > 0)
112125
{
113126
popup.VerticalOffset -= comboBox.ActualHeight;
114127
}
115128
}
116129

117-
private static FrameworkElement GetToAlignContainer(ComboBox comboBox)
130+
private static ComboBoxItem GetToAlignContainer(ComboBox comboBox)
118131
{
119132
DependencyObject container;
120133
if (comboBox.SelectedItem is null)
121134
{
122135
container = comboBox.ItemContainerGenerator.ContainerFromIndex(
123136
(int)Math.Ceiling(comboBox.Items.Count / 2.0));
124-
125-
if (comboBox.ItemContainerGenerator.ContainerFromIndex(0) is ComboBoxItem item)
126-
{
127-
var highlightedInfoProperty = typeof(ComboBox).GetProperty("HighlightedInfo",
128-
BindingFlags.Instance | BindingFlags.NonPublic);
129-
130-
var setter = highlightedInfoProperty.SetMethod;
131-
132-
var itemInfo = typeof(ComboBox)
133-
.GetMethod("ItemInfoFromContainer", BindingFlags.Instance | BindingFlags.NonPublic)?
134-
.Invoke(comboBox, [item]);
135-
136-
setter?.Invoke(comboBox, [itemInfo]);
137-
}
137+
TryHighlightingFirstItem(comboBox);
138138
}
139139
else
140140
{
141141
container = comboBox.ItemContainerGenerator.ContainerFromItem(comboBox.SelectedItem);
142142
}
143143

144-
return container as FrameworkElement;
144+
return container as ComboBoxItem;
145+
}
146+
147+
private static void TryHighlightingFirstItem(ComboBox comboBox)
148+
{
149+
if (comboBox.ItemContainerGenerator.ContainerFromIndex(0) is not ComboBoxItem item)
150+
{
151+
return;
152+
}
153+
154+
var highlightedInfoProperty = typeof(ComboBox).GetProperty("HighlightedInfo",
155+
BindingFlags.Instance | BindingFlags.NonPublic);
156+
157+
var setter = highlightedInfoProperty?.SetMethod;
158+
159+
var itemInfo = typeof(ComboBox)
160+
.GetMethod("ItemInfoFromContainer", BindingFlags.Instance | BindingFlags.NonPublic)?
161+
.Invoke(comboBox, [item]);
162+
163+
setter?.Invoke(comboBox, [itemInfo]);
145164
}
146165

147166
private static void UpdateCornerRadius(ComboBox comboBox, Popup? popup, bool isDropDownOpen, bool isOpenDown)
@@ -194,17 +213,15 @@ private static CornerRadius GetFilteredPopupRadius(CornerRadius popupRadius, boo
194213

195214
private static bool IsPopupOpenDown(ComboBox comboBox, double popupVerticalOffset)
196215
{
197-
double verticalOffset = popupVerticalOffset;
198-
if (GetTemplateChild<Border>(c_popupBorderName, comboBox) is { } popupBorder)
216+
if (GetTemplateChild<Border>(c_popupBorderName, comboBox) is not { } popupBorder ||
217+
GetTemplateChild<TextBox>(c_editableTextName, comboBox) is not { } textBox)
199218
{
200-
if (GetTemplateChild<TextBox>(c_editableTextName, comboBox) is { } textBox)
201-
{
202-
var popupTop = popupBorder.TranslatePoint(new Point(0, 0), textBox);
203-
verticalOffset = popupTop.Y;
204-
}
219+
return false;
205220
}
206-
207-
return verticalOffset > popupVerticalOffset;
221+
222+
var popupTopPoint = popupBorder.TranslatePoint(new Point(0, 0), textBox);
223+
224+
return popupTopPoint.Y + popupVerticalOffset > 0;
208225
}
209226

210227
private static object ResourceLookup(Control control, object key)

source/iNKORE.UI.WPF.Modern/Themes/Controls/ComboBox.xaml

Lines changed: 17 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -52,30 +52,8 @@
5252
<Setter Property="Padding" Value="{DynamicResource ComboBoxItemThemePadding}" />
5353
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
5454
<Setter Property="FocusVisualStyle" Value="{DynamicResource {x:Static SystemParameters.FocusVisualStyleKey}}" />
55-
<!--<Setter Property="FocusVisualStyle">
56-
<Setter.Value>
57-
<Style>
58-
<Setter Property="Control.Template">
59-
<Setter.Value>
60-
<ControlTemplate>
61-
<ikw:ClippedContent
62-
BorderBrush="{DynamicResource SystemControlFocusVisualPrimaryBrush}"
63-
BorderThickness="{TemplateBinding chelper:FocusVisualHelper.FocusVisualPrimaryThickness}"
64-
SnapsToDevicePixels="True"
65-
CornerRadius="6">
66-
<Border CornerRadius="6"
67-
BorderBrush="{DynamicResource SystemControlFocusVisualSecondaryBrush}"
68-
BorderThickness="{TemplateBinding chelper:FocusVisualHelper.FocusVisualSecondaryThickness}" />
69-
</ikw:ClippedContent>
70-
</ControlTemplate>
71-
</Setter.Value>
72-
</Setter>
73-
</Style>
74-
</Setter.Value>
75-
</Setter>-->
7655
<Setter Property="chelper:FocusVisualHelper.FocusVisualMargin" Value="-3" />
7756
<Setter Property="chelper:FocusVisualHelper.UseSystemFocusVisuals" Value="True" />
78-
<!--<Setter Property="chelper:FocusVisualHelper.UseSystemFocusVisuals" Value="False" />-->
7957
<Setter Property="chelper:ControlHelper.CornerRadius" Value="{DynamicResource ComboBoxItemCornerRadius}" />
8058
<Setter Property="Template">
8159
<Setter.Value>
@@ -95,7 +73,6 @@
9573
Grid.Row="1"
9674
Grid.Column="0"
9775
Opacity="0"
98-
RenderTransformOrigin="0.5,0.5"
9976
Style="{StaticResource ComboBoxItemPill}">
10077
<Rectangle.RenderTransform>
10178
<ScaleTransform x:Name="PillTransform" ScaleY="1" />
@@ -409,6 +386,7 @@
409386
Foreground="{DynamicResource ComboBoxHeaderForeground}"
410387
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
411388
TextWrapping="Wrap"
389+
LineHeight="20"
412390
Visibility="{TemplateBinding chelper:ControlHelper.HeaderVisibility}" />
413391
<Border
414392
x:Name="HighlightBackground"
@@ -427,11 +405,13 @@
427405
Grid.Column="0"
428406
Grid.ColumnSpan="2"
429407
MinWidth="{DynamicResource ComboBoxThemeMinWidth}"
408+
chelper:FocusVisualHelper.IsTemplateFocusTarget="True"
430409
chelper:ValidationHelper.IsTemplateValidationAdornerSite="True"
431410
Background="{TemplateBinding Background}"
432411
BorderBrush="{TemplateBinding BorderBrush}"
433412
BorderThickness="{TemplateBinding BorderThickness}"
434-
CornerRadius="{TemplateBinding chelper:ControlHelper.CornerRadius}" />
413+
CornerRadius="{TemplateBinding chelper:ControlHelper.CornerRadius}"
414+
ElevationTransitionLength="1"/>
435415
<Rectangle
436416
x:Name="Pill"
437417
Grid.Row="1"
@@ -440,13 +420,17 @@
440420
Opacity="0"
441421
Style="{StaticResource ComboBoxItemPill}">
442422
<Rectangle.RenderTransform>
443-
<TranslateTransform x:Name="PillTransform" Y="1" />
423+
<TransformGroup>
424+
<ScaleTransform x:Name="PillScaleTransform" ScaleY="1"/>
425+
<TranslateTransform x:Name="PillTransform" Y="1" />
426+
</TransformGroup>
444427
</Rectangle.RenderTransform>
445428
</Rectangle>
446429
<local:ContentPresenterEx
447430
x:Name="ContentPresenter"
448431
Grid.Row="1"
449432
Grid.Column="0"
433+
Foreground="{TemplateBinding Foreground}"
450434
Margin="{TemplateBinding Padding}"
451435
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
452436
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
@@ -483,14 +467,12 @@
483467
Grid.ColumnSpan="2"
484468
Margin="0,0,0,0"
485469
Padding="{DynamicResource ComboBoxEditableTextPadding}"
486-
HorizontalAlignment="Stretch"
487-
VerticalAlignment="Stretch"
488470
Foreground="{TemplateBinding Foreground}"
489471
FontFamily="{TemplateBinding FontFamily}"
490472
FontSize="{TemplateBinding FontSize}"
491473
FontWeight="{TemplateBinding FontWeight}"
492-
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
493-
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
474+
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
475+
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
494476
chelper:ControlHelper.CornerRadius="{TemplateBinding chelper:ControlHelper.CornerRadius}"
495477
chelper:ControlHelper.PlaceholderForeground="{TemplateBinding chelper:ControlHelper.PlaceholderForeground}"
496478
chelper:ControlHelper.PlaceholderText="{TemplateBinding chelper:ControlHelper.PlaceholderText}"
@@ -543,15 +525,15 @@
543525
Placement="Bottom"
544526
PlacementTarget="{Binding ElementName=Background}"
545527
PopupAnimation="None">
546-
<Popup.PlacementRectangle>
528+
<!--<Popup.PlacementRectangle>
547529
<MultiBinding>
548530
<MultiBinding.Converter>
549531
<ikw:PlacementRectangleConverter Margin="0,1,0,1" />
550532
</MultiBinding.Converter>
551533
<Binding ElementName="Background" Path="ActualWidth" />
552534
<Binding ElementName="Background" Path="ActualHeight" />
553535
</MultiBinding>
554-
</Popup.PlacementRectangle>
536+
</Popup.PlacementRectangle>-->
555537
<primitives:ThemeShadowChrome
556538
x:Name="Shdw"
557539
MinWidth="{Binding ActualWidth, ElementName=LayoutRoot}"
@@ -591,22 +573,22 @@
591573
<Trigger Property="IsMouseOver" Value="True">
592574
<Setter TargetName="Background" Property="Background" Value="{DynamicResource ComboBoxBackgroundPointerOver}" />
593575
<Setter TargetName="Background" Property="BorderBrush" Value="{DynamicResource ComboBoxBorderBrushPointerOver}" />
594-
<Setter Property="Foreground" Value="{DynamicResource ComboBoxForegroundPointerOver}" />
576+
<Setter TargetName="ContentPresenter" Property="Foreground" Value="{DynamicResource ComboBoxForegroundPointerOver}" />
595577
<Setter TargetName="PlaceholderTextBlock" Property="Foreground" Value="{DynamicResource ComboBoxPlaceHolderForegroundPointerOver}" />
596578
</Trigger>
597579
<!-- Pressed -->
598580
<Trigger SourceName="ToggleButton" Property="IsPressed" Value="True">
599581
<Setter TargetName="Background" Property="Background" Value="{DynamicResource ComboBoxBackgroundPressed}" />
600582
<Setter TargetName="Background" Property="BorderBrush" Value="{DynamicResource ComboBoxBorderBrushPressed}" />
601-
<Setter Property="Foreground" Value="{DynamicResource ComboBoxForegroundPressed}" />
583+
<Setter TargetName="ContentPresenter" Property="Foreground" Value="{DynamicResource ComboBoxForegroundPressed}" />
602584
<Setter TargetName="PlaceholderTextBlock" Property="Foreground" Value="{DynamicResource ComboBoxPlaceHolderForegroundPressed}" />
603585
</Trigger>
604586
<!-- Disabled -->
605587
<Trigger Property="IsEnabled" Value="False">
606588
<Setter TargetName="Background" Property="Background" Value="{DynamicResource ComboBoxBackgroundDisabled}" />
607589
<Setter TargetName="Background" Property="BorderBrush" Value="{DynamicResource ComboBoxBorderBrushDisabled}" />
608590
<Setter TargetName="HeaderContentPresenter" Property="Foreground" Value="{DynamicResource ComboBoxHeaderForegroundDisabled}" />
609-
<Setter Property="Foreground" Value="{DynamicResource ComboBoxForegroundDisabled}" />
591+
<Setter TargetName="ContentPresenter" Property="Foreground" Value="{DynamicResource ComboBoxForegroundDisabled}" />
610592
<Setter TargetName="PlaceholderTextBlock" Property="Foreground" Value="{DynamicResource ComboBoxPlaceHolderForegroundDisabled}" />
611593
<Setter TargetName="DropDownGlyph" Property="Foreground" Value="{DynamicResource ComboBoxDropDownGlyphForegroundDisabled}" />
612594
</Trigger>
@@ -627,7 +609,7 @@
627609
</MultiTrigger.Conditions>
628610
<Setter TargetName="HighlightBackground" Property="Opacity" Value="1" />
629611
<Setter TargetName="Pill" Property="Opacity" Value="1" />
630-
<Setter TargetName="ContentPresenter" Property="TextElement.Foreground" Value="{DynamicResource ComboBoxForegroundFocusedPressed}" />
612+
<Setter TargetName="ContentPresenter" Property="Foreground" Value="{DynamicResource ComboBoxForegroundFocusedPressed}" />
631613
<Setter TargetName="PlaceholderTextBlock" Property="Foreground" Value="{DynamicResource ComboBoxPlaceHolderForegroundFocusedPressed}" />
632614
<Setter TargetName="DropDownGlyph" Property="Foreground" Value="{DynamicResource ComboBoxDropDownGlyphForegroundFocusedPressed}" />
633615
</MultiTrigger>

source/iNKORE.UI.WPF.Modern/Themes/ThemeResources.xaml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,13 +68,13 @@
6868
<Thickness x:Key="ComboBoxDropdownBorderThickness">1</Thickness>
6969
<Thickness x:Key="ComboBoxHeaderThemeMargin">0,0,0,4</Thickness>
7070
<Thickness x:Key="ComboBoxPopupBorderThemeThickness">2</Thickness>
71-
<Thickness x:Key="ComboBoxItemThemePadding">11,5,11,5</Thickness>
71+
<Thickness x:Key="ComboBoxItemThemePadding">11,6.8,11,8.8</Thickness>
7272
<Thickness x:Key="ComboBoxItemThemeTouchPadding">11,11,11,13</Thickness>
73-
<Thickness x:Key="ComboBoxItemThemeGameControllerPadding">11,11,11,11</Thickness>
73+
<Thickness x:Key="ComboBoxItemThemeGameControllerPadding">11,11,11,13</Thickness>
7474
<Thickness x:Key="ComboBoxBackgroundBorderThicknessFocused">2</Thickness>
7575
<Thickness x:Key="ComboBoxDropdownContentMargin">0,4</Thickness>
7676
<Thickness x:Key="ComboBoxTopHeaderMargin">0,0,0,8</Thickness>
77-
<Thickness x:Key="ComboBoxPadding">12,5,0,5</Thickness>
77+
<Thickness x:Key="ComboBoxPadding">12,5,0,7</Thickness>
7878
<Thickness x:Key="ComboBoxEditableTextPadding">11,5,38,6</Thickness>
7979

8080
<CornerRadius x:Key="ComboBoxHiglightBorderCornerRadius">7</CornerRadius>

0 commit comments

Comments
 (0)