Skip to content

Commit d7f9297

Browse files
committed
2 parents 429dd09 + 57398c5 commit d7f9297

8 files changed

+148
-54
lines changed

MaterialDesignThemes.Wpf/ComboBoxPopup.cs

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System.Collections.Generic;
33
using System.Diagnostics;
44
using System.Linq;
5+
using System.Reflection;
56
using System.Text;
67
using System.Threading.Tasks;
78
using System.Windows;
@@ -105,34 +106,47 @@ private CustomPopupPlacement[] ComboBoxCustomPopupPlacementCallback(Size popupSi
105106
{
106107
var locationFromScreen = this.PlacementTarget.PointToScreen(new Point(0, 0));
107108

108-
int locationX = (int) locationFromScreen.X%(int) SystemParameters.PrimaryScreenWidth;
109-
int locationY = (int) locationFromScreen.Y%(int) SystemParameters.PrimaryScreenHeight;
109+
var mainVisual = PlacementTarget.GetVisualAncestory().OfType<System.Windows.Media.Visual>().LastOrDefault();
110+
if (mainVisual == null) return new CustomPopupPlacement[0];
110111

111-
if (locationX + popupSize.Width > SystemParameters.PrimaryScreenWidth || locationX < 0)
112+
var screenWidth = (int) DpiHelper.TransformToDeviceX(mainVisual, SystemParameters.PrimaryScreenWidth);
113+
var screenHeight = (int) DpiHelper.TransformToDeviceY(mainVisual, SystemParameters.PrimaryScreenHeight);
114+
115+
var locationX = (int)locationFromScreen.X % screenWidth;
116+
var locationY = (int)locationFromScreen.Y % screenHeight;
117+
118+
var realOffsetX = (popupSize.Width - targetSize.Width) / 2.0;
119+
var offsetX = DpiHelper.TransformToDeviceX(mainVisual, offset.X);
120+
var defaultVerticalOffsetIndepent = DpiHelper.TransformToDeviceY(mainVisual, DefaultVerticalOffset);
121+
var upVerticalOffsetIndepent = DpiHelper.TransformToDeviceY(mainVisual, UpVerticalOffset);
122+
var downVerticalOffsetIndepent = DpiHelper.TransformToDeviceY(mainVisual, DownVerticalOffset);
123+
124+
if (locationX + popupSize.Width - realOffsetX > screenWidth
125+
|| locationX + realOffsetX < 0)
112126
{
113127
SetChildTemplateIfNeed(DefaultContentTemplate);
114128

115-
double newY = locationY + popupSize.Height > SystemParameters.PrimaryScreenHeight
116-
? -(DefaultVerticalOffset + popupSize.Height)
117-
: DefaultVerticalOffset + targetSize.Height;
129+
var newY = locationY + popupSize.Height > screenHeight
130+
? -(defaultVerticalOffsetIndepent + popupSize.Height)
131+
: defaultVerticalOffsetIndepent + targetSize.Height;
118132

119-
return new[] { new CustomPopupPlacement(new Point(offset.X, newY), PopupPrimaryAxis.Horizontal) };
133+
return new[] { new CustomPopupPlacement(new Point(offsetX, newY), PopupPrimaryAxis.Horizontal) };
120134
}
121-
if (locationY + popupSize.Height > SystemParameters.PrimaryScreenHeight)
135+
if (locationY + popupSize.Height > screenHeight)
122136
{
123137
SetChildTemplateIfNeed(UpContentTemplate);
124138

125-
double newY = UpVerticalOffset - popupSize.Height + targetSize.Height;
139+
var newY = upVerticalOffsetIndepent - popupSize.Height + targetSize.Height;
126140

127-
return new[] { new CustomPopupPlacement(new Point(offset.X, newY), PopupPrimaryAxis.None) };
141+
return new[] { new CustomPopupPlacement(new Point(offsetX, newY), PopupPrimaryAxis.None) };
128142
}
129143
else
130144
{
131145
SetChildTemplateIfNeed(DownContentTemplate);
132146

133-
double newY = DownVerticalOffset;
147+
var newY = downVerticalOffsetIndepent;
134148

135-
return new[] { new CustomPopupPlacement(new Point(offset.X, newY), PopupPrimaryAxis.None) };
149+
return new[] { new CustomPopupPlacement(new Point(offsetX, newY), PopupPrimaryAxis.None) };
136150
}
137151
}
138152
}

MaterialDesignThemes.Wpf/DependencyObjectExtensions.cs

Lines changed: 0 additions & 18 deletions
This file was deleted.

MaterialDesignThemes.Wpf/DpiHelper.cs

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Reflection;
5+
using System.Text;
6+
using System.Threading.Tasks;
7+
using System.Windows;
8+
using System.Windows.Media;
9+
10+
namespace MaterialDesignThemes.Wpf
11+
{
12+
internal static class DpiHelper
13+
{
14+
private static readonly int DpiX;
15+
private static readonly int DpiY;
16+
17+
private const double StandartDpiX = 96.0;
18+
private const double StandartDpiY = 96.0;
19+
20+
static DpiHelper()
21+
{
22+
var dpiXProperty = typeof(SystemParameters).GetProperty("DpiX", BindingFlags.NonPublic | BindingFlags.Static);
23+
var dpiYProperty = typeof(SystemParameters).GetProperty("Dpi", BindingFlags.NonPublic | BindingFlags.Static);
24+
25+
DpiX = (int)dpiXProperty.GetValue(null, null);
26+
DpiY = (int)dpiYProperty.GetValue(null, null);
27+
}
28+
29+
public static double TransformToDeviceY(Visual visual, double y)
30+
{
31+
var source = PresentationSource.FromVisual(visual);
32+
if (source?.CompositionTarget != null) return y * source.CompositionTarget.TransformToDevice.M22;
33+
34+
return TransformToDeviceY(y);
35+
}
36+
37+
public static double TransformToDeviceX(Visual visual, double x)
38+
{
39+
var source = PresentationSource.FromVisual(visual);
40+
if (source?.CompositionTarget != null) return x * source.CompositionTarget.TransformToDevice.M11;
41+
42+
return TransformToDeviceX(x);
43+
}
44+
45+
public static double TransformToDeviceY(double y)
46+
{
47+
return y * DpiY / StandartDpiY;
48+
}
49+
50+
public static double TransformToDeviceX(double x)
51+
{
52+
return x * DpiX / StandartDpiX;
53+
}
54+
}
55+
}

MaterialDesignThemes.Wpf/Extensions.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,5 +28,19 @@ public static bool IsDescendant(this DependencyObject parent, DependencyObject n
2828
{
2929
return node != null && parent.VisualDepthFirstTraversal().Contains(node);
3030
}
31+
32+
/// <summary>
33+
/// Returns full visual ancestory, starting at the leaf.
34+
/// </summary>
35+
/// <param name="leaf"></param>
36+
/// <returns></returns>
37+
public static IEnumerable<DependencyObject> GetVisualAncestory(this DependencyObject leaf)
38+
{
39+
while (leaf != null)
40+
{
41+
yield return leaf;
42+
leaf = VisualTreeHelper.GetParent(leaf);
43+
}
44+
}
3145
}
3246
}

MaterialDesignThemes.Wpf/MaterialDesignThemes.Wpf.csproj

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,13 +241,13 @@
241241
<Compile Include="CustomPopupPlacementCallbackHelper.cs" />
242242
<Compile Include="DataGridAssist.cs" />
243243
<Compile Include="DateTimeEx.cs" />
244-
<Compile Include="DependencyObjectExtensions.cs" />
245244
<Compile Include="DialogClosingEventArgs.cs" />
246245
<Compile Include="DialogClosingEventHandler.cs" />
247246
<Compile Include="DialogOpenedEventArgs.cs" />
248247
<Compile Include="DialogOpenedEventHandler.cs" />
249248
<Compile Include="DialogSession.cs" />
250249
<Compile Include="DialogHost.cs" />
250+
<Compile Include="DpiHelper.cs" />
251251
<Compile Include="DrawerHost.cs" />
252252
<Compile Include="Extensions.cs" />
253253
<Compile Include="ListSortDirectionIndicator.cs" />
@@ -281,6 +281,7 @@
281281
<Compile Include="RippleAssist.cs" />
282282
<Compile Include="Ripple.cs" />
283283
<Compile Include="TransitionAssist.cs" />
284+
<Compile Include="TreeHelper.cs" />
284285
<Compile Include="Underline.cs" />
285286
<Compile Include="ValidationAssist.cs" />
286287
<EmbeddedResource Include="Properties\Resources.resx">

MaterialDesignThemes.Wpf/Themes/MaterialDesignTheme.ComboBox.xaml

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@
8686

8787
<ControlTemplate x:Key="PopupContentDownTemplate" TargetType="ContentControl">
8888
<Grid MinWidth="{Binding ElementName=templateRoot, Path=ActualWidth, Converter={StaticResource MathAddConverter}, ConverterParameter=32}"
89-
Margin="6">
89+
Margin="6">
9090
<Grid.RowDefinitions>
9191
<RowDefinition Height="*" />
9292
</Grid.RowDefinitions>
@@ -98,7 +98,8 @@
9898
<BlurEffect Radius="6"/>
9999
</Border.Effect>
100100
</Border>
101-
<Grid Margin="1">
101+
<Grid Margin="1"
102+
SnapsToDevicePixels="True">
102103
<Grid.RowDefinitions>
103104
<RowDefinition Height="Auto"/>
104105
<RowDefinition Height="Auto"/>
@@ -107,35 +108,37 @@
107108
<RowDefinition Height="Auto"/>
108109
</Grid.RowDefinitions>
109110
<Rectangle Grid.Row="0"
110-
Fill="{DynamicResource MaterialDesignPaper}"
111-
Height="{StaticResource PopupTopBottomMargin}"/>
112-
111+
Fill="{DynamicResource MaterialDesignPaper}"
112+
Height="{StaticResource PopupTopBottomMargin}"/>
113+
113114
<Grid Grid.Row="1">
114115
<Grid.ColumnDefinitions>
115116
<ColumnDefinition Width="Auto"/>
116117
<ColumnDefinition Width="Auto"/>
117118
<ColumnDefinition Width="*"/>
118119
</Grid.ColumnDefinitions>
119120
<Rectangle Grid.Column="0"
120-
Width="{StaticResource PopupLeftRightMargin}"
121-
Fill="{DynamicResource MaterialDesignPaper}"/>
121+
Width="{StaticResource PopupLeftRightMargin}"
122+
Fill="{DynamicResource MaterialDesignPaper}"
123+
/>
122124
<Grid Grid.Column="1"
123-
Width="{Binding ElementName=templateRoot, Path=ActualWidth}"
124-
Height="{Binding ElementName=templateRoot, Path=ActualHeight}"/>
125+
Width="{Binding ElementName=templateRoot, Path=ActualWidth}"
126+
Height="{Binding ElementName=templateRoot, Path=ActualHeight}"/>
125127
<Rectangle Grid.Column="2"
126-
MinWidth="{StaticResource PopupLeftRightMargin}"
127-
Fill="{DynamicResource MaterialDesignPaper}"/>
128+
MinWidth="{StaticResource PopupLeftRightMargin}"
129+
Fill="{DynamicResource MaterialDesignPaper}"
130+
/>
128131
</Grid>
129132

130133
<Rectangle Grid.Row="2"
131-
Fill="{DynamicResource MaterialDesignPaper}"
132-
Height="{StaticResource PopupContentPresenterExtend}"/>
134+
Fill="{DynamicResource MaterialDesignPaper}"
135+
Height="{StaticResource PopupContentPresenterExtend}"/>
133136

134137
<ContentPresenter Grid.Row="3"/>
135138

136139
<Rectangle Grid.Row="4"
137-
Height="{StaticResource PopupTopBottomMargin}"
138-
Fill="{DynamicResource MaterialDesignPaper}" />
140+
Height="{StaticResource PopupTopBottomMargin}"
141+
Fill="{DynamicResource MaterialDesignPaper}" />
139142
</Grid>
140143
</Grid>
141144
</ControlTemplate>
@@ -385,8 +388,7 @@
385388

386389
<ControlTemplate x:Key="MaterialDesignComboBoxTemplate" TargetType="{x:Type ComboBox}">
387390
<Grid x:Name="templateRoot"
388-
SnapsToDevicePixels="True"
389-
UseLayoutRounding="True">
391+
SnapsToDevicePixels="True">
390392
<Grid.ColumnDefinitions>
391393
<ColumnDefinition Width="*" />
392394
<ColumnDefinition Width="0" MinWidth="{DynamicResource {x:Static SystemParameters.VerticalScrollBarWidthKey}}" />
@@ -434,9 +436,8 @@
434436
HorizontalOffset="-11"
435437
IsOpen="{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}"
436438
PlacementTarget="{Binding ElementName=templateRoot}"
437-
SnapsToDevicePixels="True"
438-
UseLayoutRounding="True"
439439
Placement="Custom"
440+
SnapsToDevicePixels="True"
440441
PopupAnimation="Fade"
441442
VerticalOffset="0"
442443
DefaultVerticalOffset="5"
@@ -486,7 +487,8 @@
486487
</ControlTemplate>
487488

488489
<ControlTemplate x:Key="MaterialDesignFloatingHintComboBoxTemplate" TargetType="{x:Type ComboBox}">
489-
<Grid x:Name="templateRoot">
490+
<Grid x:Name="templateRoot"
491+
SnapsToDevicePixels="True">
490492
<VisualStateManager.VisualStateGroups>
491493
<VisualStateGroup x:Name="MaterialDesignStates">
492494
<VisualStateGroup.Transitions>
@@ -557,9 +559,7 @@
557559
</VisualState>
558560
</VisualStateGroup>
559561
</VisualStateManager.VisualStateGroups>
560-
<Grid Margin="0 12 0 0"
561-
SnapsToDevicePixels="True"
562-
UseLayoutRounding="True">
562+
<Grid Margin="0 12 0 0">
563563
<Grid.ColumnDefinitions>
564564
<ColumnDefinition Width="*" />
565565
<ColumnDefinition Width="0" MinWidth="{DynamicResource {x:Static SystemParameters.VerticalScrollBarWidthKey}}" />
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
using System.Windows;
7+
using System.Windows.Controls.Primitives;
8+
using System.Windows.Media;
9+
10+
namespace MaterialDesignThemes.Wpf
11+
{
12+
internal static class TreeHelper
13+
{
14+
public static Visual FindMainTreeVisual(Visual visual)
15+
{
16+
DependencyObject root = null;
17+
DependencyObject dependencyObject = visual;
18+
19+
while (dependencyObject != null)
20+
{
21+
root = dependencyObject;
22+
dependencyObject = VisualTreeHelper.GetParent(dependencyObject);
23+
}
24+
25+
return root as Visual;
26+
}
27+
}
28+
}

MaterialDesignToolkit.Wpf.sln.vsext.disable

Whitespace-only changes.

0 commit comments

Comments
 (0)