Skip to content

Commit b12fe2c

Browse files
committed
ComboBoxPopup transparency working fine
1 parent 3c30be7 commit b12fe2c

File tree

6 files changed

+114
-70
lines changed

6 files changed

+114
-70
lines changed

MaterialDesignThemes.Wpf/ComboBoxPopup.cs

Lines changed: 57 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,21 @@
11
using System;
2+
using System.Collections.Generic;
3+
using System.Diagnostics;
24
using System.Linq;
35
using System.Windows;
46
using System.Windows.Controls;
57
using System.Windows.Controls.Primitives;
8+
using System.Windows.Data;
69
using System.Windows.Media;
710

811
namespace MaterialDesignThemes.Wpf
912
{
1013
public class ComboBoxPopup : Popup
1114
{
15+
public const double ContentPresenterExtend = 4;
16+
public const double TopBottomMargin = 8;
17+
public const double LeftRightMargin = 32;
18+
1219
public static readonly DependencyProperty UpContentTemplateProperty
1320
= DependencyProperty.Register(nameof(UpContentTemplate),
1421
typeof(ControlTemplate),
@@ -69,6 +76,23 @@ public double DownVerticalOffset
6976
set { SetValue(DownVerticalOffsetProperty, value); }
7077
}
7178

79+
#region Background property
80+
81+
public static readonly DependencyProperty BackgroundProperty
82+
= DependencyProperty.Register(nameof(Background),
83+
typeof(Brush),
84+
typeof(ComboBoxPopup),
85+
new FrameworkPropertyMetadata(Brushes.Transparent, FrameworkPropertyMetadataOptions.AffectsRender));
86+
87+
88+
public Brush Background
89+
{
90+
get { return (Brush) GetValue(BackgroundProperty); }
91+
set { SetValue(BackgroundProperty, value); }
92+
}
93+
94+
#endregion
95+
7296
#region DefaultVerticalOffset
7397

7498
public static readonly DependencyProperty DefaultVerticalOffsetProperty
@@ -117,12 +141,36 @@ private void SetChildTemplateIfNeed(ControlTemplate template)
117141
}
118142
}
119143

120-
private CustomPopupPlacement[] ComboBoxCustomPopupPlacementCallback(Size popupSize, Size targetSize,
121-
Point offset)
144+
private void SetupBackground(IEnumerable<DependencyObject> visualAncestry)
145+
{
146+
var background = visualAncestry
147+
.Select(v => (v as Control)?.Background ?? (v as Border)?.Background)
148+
.FirstOrDefault(v => v != null && v != Brushes.Transparent && v is SolidColorBrush);
149+
150+
if (background != null)
151+
{
152+
Background = background;
153+
}
154+
}
155+
156+
private void SetupVisiblePlacementWidth(IEnumerable<DependencyObject> visualAncestry)
157+
{
158+
var parent = visualAncestry.OfType<Panel>().ElementAt(1);
159+
VisiblePlacementWidth = TreeHelper.GetVisibleWidth((FrameworkElement)PlacementTarget, parent);
160+
}
161+
162+
private CustomPopupPlacement[] ComboBoxCustomPopupPlacementCallback(
163+
Size popupSize, Size targetSize, Point offset)
122164
{
123-
var locationFromScreen = this.PlacementTarget.PointToScreen(new Point(0, 0));
165+
var visualAncestry = PlacementTarget.GetVisualAncestry().ToList();
124166

125-
var mainVisual = PlacementTarget.GetVisualAncestry().OfType<Visual>().LastOrDefault();
167+
SetupBackground(visualAncestry);
168+
169+
SetupVisiblePlacementWidth(visualAncestry);
170+
171+
var locationFromScreen = PlacementTarget.PointToScreen(new Point(0, 0));
172+
173+
var mainVisual = visualAncestry.OfType<Visual>().LastOrDefault();
126174
if (mainVisual == null) return new CustomPopupPlacement[0];
127175

128176
var screenWidth = (int) DpiHelper.TransformToDeviceX(mainVisual, SystemParameters.PrimaryScreenWidth);
@@ -142,28 +190,25 @@ private CustomPopupPlacement[] ComboBoxCustomPopupPlacementCallback(Size popupSi
142190
offsetX = DpiHelper.TransformToDeviceX(mainVisual,
143191
offset.X - targetSize.Width - rtlHorizontalOffset);
144192

145-
var defaultVerticalOffsetIndepent = DpiHelper.TransformToDeviceY(mainVisual, DefaultVerticalOffset);
146-
var upVerticalOffsetIndepent = DpiHelper.TransformToDeviceY(mainVisual, UpVerticalOffset);
147-
var downVerticalOffsetIndepent = DpiHelper.TransformToDeviceY(mainVisual, DownVerticalOffset);
148-
var parent = this.PlacementTarget.GetVisualAncestry().OfType<Panel>().ElementAt(1);
149-
150-
VisiblePlacementWidth = TreeHelper.GetVisibleWidth((FrameworkElement)PlacementTarget, parent);
151193

152194
if (locationX + popupSize.Width - realOffsetX > screenWidth
153-
|| locationX + realOffsetX < 0)
195+
|| locationX - realOffsetX < 0)
154196
{
155197
SetChildTemplateIfNeed(DefaultContentTemplate);
156198

199+
var defaultVerticalOffsetIndepent = DpiHelper.TransformToDeviceY(mainVisual, DefaultVerticalOffset);
157200
var newY = locationY + popupSize.Height > screenHeight
158201
? -(defaultVerticalOffsetIndepent + popupSize.Height)
159202
: defaultVerticalOffsetIndepent + targetSize.Height;
160203

161204
return new[] { new CustomPopupPlacement(new Point(offsetX, newY), PopupPrimaryAxis.Horizontal) };
162205
}
206+
163207
if (locationY + popupSize.Height > screenHeight)
164208
{
165209
SetChildTemplateIfNeed(UpContentTemplate);
166210

211+
var upVerticalOffsetIndepent = DpiHelper.TransformToDeviceY(mainVisual, UpVerticalOffset);
167212
var newY = upVerticalOffsetIndepent - popupSize.Height + targetSize.Height;
168213

169214
return new[] { new CustomPopupPlacement(new Point(offsetX, newY), PopupPrimaryAxis.None) };
@@ -172,6 +217,7 @@ private CustomPopupPlacement[] ComboBoxCustomPopupPlacementCallback(Size popupSi
172217
{
173218
SetChildTemplateIfNeed(DownContentTemplate);
174219

220+
var downVerticalOffsetIndepent = DpiHelper.TransformToDeviceY(mainVisual, DownVerticalOffset);
175221
var newY = downVerticalOffsetIndepent;
176222

177223
return new[] { new CustomPopupPlacement(new Point(offsetX, newY), PopupPrimaryAxis.None) };

MaterialDesignThemes.Wpf/Converters/BrushRoundConverter.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ public class BrushRoundConverter : IValueConverter
1515
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
1616
{
1717
var solidColorBrush = value as SolidColorBrush;
18-
if (solidColorBrush == null) return Binding.DoNothing;
18+
if (solidColorBrush == null) return null;
1919

2020
var color = solidColorBrush.Color;
2121

MaterialDesignThemes.Wpf/Themes/Generic.xaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -850,8 +850,8 @@
850850
</Setter>
851851
</Style>
852852

853-
<Style TargetType="{x:Type transitions:TransitioningContentBase}">
854-
<Setter Property="KeyboardNavigation.IsTabStop" Value="False"/>
853+
<Style TargetType="{x:Type transitions:TransitioningContentBase}">
854+
<Setter Property="KeyboardNavigation.IsTabStop" Value="False"/>
855855
<Setter Property="Template">
856856
<Setter.Value>
857857
<ControlTemplate TargetType="{x:Type transitions:TransitioningContentBase}">

MaterialDesignThemes.Wpf/Themes/MaterialDesignTheme.ComboBox.xaml

Lines changed: 52 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,11 @@
2626
</Setter.Value>
2727
</Setter>
2828
</Style>
29-
30-
<system:Double x:Key="PopupContentPresenterExtend">4</system:Double>
31-
<system:Double x:Key="PopupTopBottomMargin">8</system:Double>
29+
3230
<system:Double x:Key="PopupLeftRightMargin">16</system:Double>
3331

3432
<ControlTemplate x:Key="PopupContentUpTemplate" TargetType="ContentControl">
35-
<Grid MinWidth="{Binding ElementName=templateRoot, Path=ActualWidth, Converter={StaticResource MathAddConverter}, ConverterParameter=32}"
33+
<Grid MinWidth="{Binding ElementName=templateRoot, Path=ActualWidth, Converter={StaticResource MathAddConverter}, ConverterParameter={x:Static wpf:ComboBoxPopup.LeftRightMargin}}"
3634
Margin="6">
3735
<Grid.RowDefinitions>
3836
<RowDefinition Height="*" />
@@ -55,40 +53,40 @@
5553
</Grid.RowDefinitions>
5654
<Border Grid.Row="0"
5755
CornerRadius="2 2 0 0"
58-
Background="{Binding ElementName=templateRoot, Path=Background}"
59-
Height="{StaticResource PopupTopBottomMargin}"/>
56+
Background="{Binding ElementName=PART_Popup, Path=Background}"
57+
Height="{x:Static wpf:ComboBoxPopup.TopBottomMargin}"/>
6058
<ContentPresenter Grid.Row="1"/>
61-
<Rectangle Grid.Row="2"
62-
Fill="{Binding ElementName=templateRoot, Path=Background}"
63-
Height="{StaticResource PopupContentPresenterExtend}"/>
59+
<Border Grid.Row="2"
60+
Background="{Binding ElementName=PART_Popup, Path=Background}"
61+
Height="{x:Static wpf:ComboBoxPopup.ContentPresenterExtend}"/>
6462

6563
<Grid Grid.Row="3">
6664
<Grid.ColumnDefinitions>
6765
<ColumnDefinition Width="Auto"/>
6866
<ColumnDefinition Width="Auto"/>
6967
<ColumnDefinition Width="*"/>
7068
</Grid.ColumnDefinitions>
71-
<Rectangle Grid.Column="0"
72-
Width="{StaticResource PopupLeftRightMargin}"
73-
Fill="{Binding ElementName=templateRoot, Path=Background}"/>
69+
<Border Grid.Column="0"
70+
Width="{StaticResource PopupLeftRightMargin}"
71+
Background="{Binding ElementName=PART_Popup, Path=Background}"/>
7472
<Grid Grid.Column="1"
7573
Width="{Binding RelativeSource={RelativeSource AncestorType={x:Type wpf:ComboBoxPopup}}, Path=VisiblePlacementWidth}"
7674
Height="{Binding ElementName=templateRoot, Path=ActualHeight}"/>
77-
<Rectangle Grid.Column="2"
78-
MinWidth="{StaticResource PopupLeftRightMargin}"
79-
Fill="{Binding ElementName=templateRoot, Path=Background}"/>
75+
<Border Grid.Column="2"
76+
MinWidth="{StaticResource PopupLeftRightMargin}"
77+
Background="{Binding ElementName=PART_Popup, Path=Background}"/>
8078
</Grid>
8179

8280
<Border Grid.Row="4"
8381
CornerRadius="0 0 2 2"
84-
Height="{StaticResource PopupTopBottomMargin}"
85-
Background="{Binding ElementName=templateRoot, Path=Background}" />
82+
Height="{x:Static wpf:ComboBoxPopup.TopBottomMargin}"
83+
Background="{Binding ElementName=PART_Popup, Path=Background}" />
8684
</Grid>
8785
</Grid>
8886
</ControlTemplate>
8987

9088
<ControlTemplate x:Key="PopupContentDownTemplate" TargetType="ContentControl">
91-
<Grid MinWidth="{Binding ElementName=templateRoot, Path=ActualWidth, Converter={StaticResource MathAddConverter}, ConverterParameter=32}"
89+
<Grid MinWidth="{Binding ElementName=templateRoot, Path=ActualWidth, Converter={StaticResource MathAddConverter}, ConverterParameter={x:Static wpf:ComboBoxPopup.LeftRightMargin}}"
9290
Margin="6">
9391
<Grid.RowDefinitions>
9492
<RowDefinition Height="*" />
@@ -112,44 +110,44 @@
112110
</Grid.RowDefinitions>
113111
<Border Grid.Row="0"
114112
CornerRadius="2 2 0 0"
115-
Background="{Binding ElementName=templateRoot, Path=Background}"
116-
Height="{StaticResource PopupTopBottomMargin}"/>
113+
Background="{Binding ElementName=PART_Popup, Path=Background}"
114+
Height="{x:Static wpf:ComboBoxPopup.TopBottomMargin}"/>
117115

118116
<Grid Grid.Row="1">
119117
<Grid.ColumnDefinitions>
120118
<ColumnDefinition Width="Auto"/>
121119
<ColumnDefinition Width="Auto"/>
122120
<ColumnDefinition Width="*"/>
123121
</Grid.ColumnDefinitions>
124-
<Rectangle Grid.Column="0"
125-
Width="{StaticResource PopupLeftRightMargin}"
126-
Fill="{Binding ElementName=templateRoot, Path=Background}"
122+
<Border Grid.Column="0"
123+
Width="{StaticResource PopupLeftRightMargin}"
124+
Background="{Binding ElementName=PART_Popup, Path=Background}"
127125
/>
128126
<Grid Grid.Column="1"
129127
Width="{Binding RelativeSource={RelativeSource AncestorType={x:Type wpf:ComboBoxPopup}}, Path=VisiblePlacementWidth}"
130128
Height="{Binding ElementName=templateRoot, Path=ActualHeight}"/>
131-
<Rectangle Grid.Column="2"
132-
MinWidth="{StaticResource PopupLeftRightMargin}"
133-
Fill="{Binding ElementName=templateRoot, Path=Background}"
129+
<Border Grid.Column="2"
130+
MinWidth="{StaticResource PopupLeftRightMargin}"
131+
Background="{Binding ElementName=PART_Popup, Path=Background}"
134132
/>
135133
</Grid>
136134

137-
<Rectangle Grid.Row="2"
138-
Fill="{Binding ElementName=templateRoot, Path=Background}"
139-
Height="{StaticResource PopupContentPresenterExtend}"/>
135+
<Border Grid.Row="2"
136+
Background="{Binding ElementName=PART_Popup, Path=Background}"
137+
Height="{x:Static wpf:ComboBoxPopup.ContentPresenterExtend}"/>
140138

141139
<ContentPresenter Grid.Row="3"/>
142140

143141
<Border Grid.Row="4"
144142
CornerRadius="0 0 2 2"
145-
Height="{StaticResource PopupTopBottomMargin}"
146-
Background="{Binding ElementName=templateRoot, Path=Background}" />
143+
Height="{x:Static wpf:ComboBoxPopup.TopBottomMargin}"
144+
Background="{Binding ElementName=PART_Popup, Path=Background}" />
147145
</Grid>
148146
</Grid>
149147
</ControlTemplate>
150148

151149
<ControlTemplate x:Key="PopupContentDefaultTemplate" TargetType="ContentControl">
152-
<Grid MinWidth="{Binding ElementName=templateRoot, Path=ActualWidth, Converter={StaticResource MathAddConverter}, ConverterParameter=32}"
150+
<Grid MinWidth="{Binding ElementName=templateRoot, Path=ActualWidth, Converter={StaticResource MathAddConverter}, ConverterParameter={x:Static wpf:ComboBoxPopup.LeftRightMargin}}"
153151
Margin="6">
154152
<Grid.RowDefinitions>
155153
<RowDefinition Height="*" />
@@ -170,15 +168,15 @@
170168
</Grid.RowDefinitions>
171169
<Border Grid.Row="0"
172170
CornerRadius="2 2 0 0"
173-
Background="{Binding ElementName=templateRoot, Path=Background}"
174-
Height="{StaticResource PopupTopBottomMargin}"/>
171+
Background="{Binding ElementName=PART_Popup, Path=Background}"
172+
Height="{x:Static wpf:ComboBoxPopup.TopBottomMargin}"/>
175173

176174
<ContentPresenter Grid.Row="1"/>
177175

178176
<Border Grid.Row="2"
179177
CornerRadius="0 0 2 2"
180-
Height="{StaticResource PopupTopBottomMargin}"
181-
Background="{Binding ElementName=templateRoot, Path=Background}" />
178+
Height="{x:Static wpf:ComboBoxPopup.TopBottomMargin}"
179+
Background="{Binding ElementName=PART_Popup, Path=Background}" />
182180
</Grid>
183181
</Grid>
184182
</ControlTemplate>
@@ -441,25 +439,25 @@
441439
Visibility="{Binding Path=(wpf:TextFieldAssist.DecorationVisibility), RelativeSource={RelativeSource TemplatedParent}}"/>
442440

443441
<wpf:ComboBoxPopup x:Name="PART_Popup"
444-
AllowsTransparency="true"
445-
Focusable="False"
446-
HorizontalOffset="-11.5"
447-
IsOpen="{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}"
448-
PlacementTarget="{Binding ElementName=templateRoot}"
449-
SnapsToDevicePixels="True"
450-
UseLayoutRounding="True"
451-
Placement="Custom"
452-
PopupAnimation="Fade"
453-
VerticalOffset="0"
454-
DefaultVerticalOffset="5"
455-
DownVerticalOffset="-15.5"
456-
UpVerticalOffset="15"
457-
UpContentTemplate="{StaticResource PopupContentUpTemplate}"
458-
DownContentTemplate="{StaticResource PopupContentDownTemplate}"
459-
DefaultContentTemplate="{StaticResource PopupContentDefaultTemplate}">
442+
AllowsTransparency="true"
443+
Focusable="False"
444+
HorizontalOffset="-11.5"
445+
IsOpen="{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}"
446+
PlacementTarget="{Binding ElementName=templateRoot}"
447+
SnapsToDevicePixels="True"
448+
UseLayoutRounding="True"
449+
Placement="Custom"
450+
PopupAnimation="Fade"
451+
VerticalOffset="0"
452+
DefaultVerticalOffset="5"
453+
DownVerticalOffset="-15.5"
454+
UpVerticalOffset="15"
455+
UpContentTemplate="{StaticResource PopupContentUpTemplate}"
456+
DownContentTemplate="{StaticResource PopupContentDownTemplate}"
457+
DefaultContentTemplate="{StaticResource PopupContentDefaultTemplate}">
460458
<ContentControl>
461459
<ScrollViewer MaxHeight="{TemplateBinding MaxDropDownHeight}"
462-
Background="{TemplateBinding Background}">
460+
Background="{Binding Background, ElementName=PART_Popup}">
463461
<ItemsPresenter x:Name="ItemsPresenter" KeyboardNavigation.DirectionalNavigation="Contained" />
464462
</ScrollViewer>
465463
</ContentControl>
@@ -522,7 +520,7 @@
522520

523521
<Style x:Key="MaterialDesignComboBox" TargetType="{x:Type ComboBox}">
524522
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
525-
<Setter Property="Background" Value="{DynamicResource MaterialDesignPaper}"/>
523+
<Setter Property="Background" Value="Transparent"/>
526524
<Setter Property="BorderBrush" Value="{DynamicResource MaterialDesignTextBoxBorder}"/>
527525
<Setter Property="Foreground" Value="{Binding RelativeSource={RelativeSource AncestorType={x:Type FrameworkElement}}, Path=(TextElement.Foreground)}"/>
528526
<Setter Property="BorderThickness" Value="0 0 0 1"/>

MaterialDesignThemes.Wpf/Themes/MaterialDesignTheme.ScrollBar.xaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@
8787
<Style x:Key="MaterialDesignScrollBar" TargetType="{x:Type ScrollBar}">
8888
<Setter Property="Stylus.IsPressAndHoldEnabled" Value="false"/>
8989
<Setter Property="Stylus.IsFlicksEnabled" Value="false"/>
90-
<Setter Property="Background" Value="{DynamicResource MaterialDesignPaper}"/>
90+
<Setter Property="Background" Value="Transparent"/>
9191
<Setter Property="BorderBrush" Value="Transparent"/>
9292
<Setter Property="Foreground" Value="{DynamicResource MaterialDesignSelection}"/>
9393
<Setter Property="BorderThickness" Value="1,0"/>

MaterialDesignThemes.Wpf/TreeHelper.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ public static double GetVisibleWidth(FrameworkElement element, UIElement parent)
2727
return width;
2828
}
2929

30-
//BinarySearch there
30+
//BinarySearch here
3131
int end = (int) Math.Floor(element.ActualWidth);
3232
int start = 0;
3333

0 commit comments

Comments
 (0)