Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
169 commits
Select commit Hold shift + click to select a range
cf9f16c
First try with a totally different glow (inspired by visual studio)
batzen May 20, 2020
13adb21
Using enum values
batzen May 20, 2020
a80fcef
Using a transparent color when brush is null
batzen Jul 25, 2020
fd26b42
Making code CLS compliant
batzen Sep 20, 2020
cfa00a9
Removing trace code
batzen Oct 3, 2020
d61b7e6
Improving showcase
batzen Oct 3, 2020
4fa884e
nullable enable
batzen Oct 13, 2020
82f43c4
Fixing nullable
batzen Feb 28, 2021
a682a24
Improving variable naming and equality checks
batzen Apr 25, 2021
8833668
Using enumerations instead of int values
batzen Apr 25, 2021
203ec80
Improving equality check
batzen Apr 25, 2021
ba1bfeb
We now call dispose explicitly
batzen Apr 25, 2021
0403dbe
Fixing hit test result
batzen Apr 25, 2021
aef1b9d
Improving showcase application
batzen Apr 25, 2021
bcf1244
Adding INotifyPropertyChanged to some classes to prevent binding leaks
batzen Apr 28, 2021
6cfb5c2
Fixing compiler errors
batzen Apr 29, 2021
a94ed42
Enabling dynamic GlowDepth
batzen May 1, 2021
86dfa7a
Fixing nullable
batzen May 1, 2021
b21f9e7
Making use of IsGlowTransitionEnabled
batzen May 1, 2021
658c9b0
Using a RadialGradient for the glow corners
batzen May 23, 2021
b52c468
Adding known boxes for various types to prevent boxing
batzen Jun 12, 2021
1513324
Updating dependencies
batzen Jun 12, 2021
0e80912
Adding DisableWinExeOutputInference to prevent issues in the future
batzen Aug 8, 2021
df76f03
Adding ShowInTaskbar to showcase
batzen Aug 8, 2021
b9fc95b
First working draft for Windows 11 support
batzen Sep 26, 2021
3ec6710
Fixing indentation
batzen Oct 2, 2021
3874d1c
Adding convenience overload
batzen Oct 12, 2021
e34daeb
Using switch expression
batzen Oct 12, 2021
4edba7c
Using pattern matching
batzen Oct 12, 2021
314013e
Removing unused code
batzen Oct 12, 2021
52abec6
Disabling warning for unused member
batzen Oct 12, 2021
951b70a
Excluding theme template from ReSharper inspections
batzen Oct 12, 2021
4539a35
Moving SuppressRedrawScope to separate file
batzen Oct 12, 2021
a8784ba
Adding hwnd to user dictionary
batzen Oct 12, 2021
8f943dd
Re-ordering methods
batzen Oct 12, 2021
75c0f57
Improving naming
batzen Oct 12, 2021
ef54cb4
Fixing typo
batzen Oct 12, 2021
41f217b
Getting GlowWindowBehavior ready for NC area
batzen Oct 13, 2021
12708fa
Improving showcase
batzen Oct 13, 2021
23f9fdc
Making AreClose an extension
batzen Oct 13, 2021
a94ea1c
Improving RECT
batzen Oct 13, 2021
04b72b0
Ignoring _wpftmp.csproj
batzen Oct 13, 2021
291a81b
First working version for rounded corners
batzen Oct 13, 2021
db9addb
Improving showcase application
batzen Oct 13, 2021
64df632
Fixing visual parent issue
batzen Oct 13, 2021
5217198
Improving resize area
batzen Oct 13, 2021
7be2e27
Making changes to ResizeBorderThickness now has an immediate effect
batzen Oct 13, 2021
c0f7345
Adding GetDCEx
batzen Oct 13, 2021
237d752
Further improving resize behavior
batzen Oct 13, 2021
1d1cd88
Removing unused method
batzen Oct 13, 2021
512c47a
We don't have to force WindowStyle=None anymore
batzen Oct 13, 2021
48123ca
Improving showcase
batzen Oct 13, 2021
fb9067f
Only modify NC-area if WS.Caption is set
batzen Oct 13, 2021
b470bac
Fixing hit testing
batzen Oct 13, 2021
7cf5c62
Adding NativeResizeBorderThickness
batzen Oct 13, 2021
104ffaf
Fixing GetDefaultResizeBorderThickness
batzen Oct 13, 2021
ebb4242
Fixing conditions
batzen Oct 13, 2021
b6b5771
Making code clearer
batzen Oct 13, 2021
f3d49e7
Making hit testing less agressive
batzen Oct 13, 2021
73da731
Using typed code
batzen Oct 13, 2021
46b24d9
Removing explicit style setter
batzen Oct 13, 2021
278509e
Fixing naming
batzen Oct 14, 2021
a33d243
Improving showcase
batzen Oct 14, 2021
fc47f55
Adding some DWM stuff
batzen Oct 14, 2021
adad917
Improving showcase
batzen Oct 14, 2021
44ef36a
Adding ToString for POINT
batzen Oct 14, 2021
5202da0
Fixing size calculation
batzen Oct 14, 2021
5ae9386
Fixing IgnoreTaskbarOnMaximize
batzen Oct 14, 2021
65a6c7d
Adding some disabled tracing to ease future investigations
batzen Oct 14, 2021
2844277
Combining Win11 support and new glow
batzen Oct 14, 2021
c86764f
Improving glow corner rendering
batzen Oct 14, 2021
bdf94ef
Improving perf when glow depth is 1
batzen Oct 14, 2021
ad7eea6
Fixing wrongly sized black rect when glow depth is < 6
batzen Oct 14, 2021
9f0c42f
Improving resize area on caption bar
batzen Oct 15, 2021
3d8fa69
Don't do hit testing for resize when we are maximized
batzen Oct 15, 2021
3404c93
Let Windows calculate the NC-size and just delete the titlebar
batzen Oct 15, 2021
114aada
Making cornerGripThickness a fixed value
batzen Oct 15, 2021
8473770
Adding "test" for glow bitmap generation
batzen Oct 15, 2021
8482ef1
Adding COLORREF
batzen Oct 15, 2021
9f5dd34
Changing GlowBrush to GlowColor
batzen Oct 15, 2021
a32237f
Only show glow windows if GlowDepth > 0
batzen Oct 15, 2021
6ea508c
Adding some more DWM interop
batzen Oct 17, 2021
dc0e47f
We can dispose the GlowWindow as soon as it gets destroyed
batzen Oct 17, 2021
94a6037
Adding CornerPreference
batzen Oct 17, 2021
7de87fc
Adding native DWM border color capabilities
batzen Oct 18, 2021
2ce0377
Checking IsDisposed before doing anything
batzen Oct 18, 2021
ab50000
Improving showcase
batzen Oct 18, 2021
bb6d184
Improving resize-prevention
batzen Oct 18, 2021
7feddde
Improving showcase by making Background changeable
batzen Oct 18, 2021
3213f54
Preventing window update if width or height are zero
batzen Oct 19, 2021
fea1259
Fixing GDI handle leak
batzen Oct 19, 2021
e9b52d7
Adding animated glow depth to showcase
batzen Oct 19, 2021
05f5202
Re-Enabling z-order code
batzen Oct 19, 2021
19947bc
Fixing naming and adding doc comment
batzen Oct 19, 2021
bb8de8c
Improving naming
batzen Oct 19, 2021
80ba48b
Disabling sending NCACTIVATE
batzen Oct 19, 2021
c187f2f
Adding more DWM methods
batzen Oct 19, 2021
1869e67
Improving tracing
batzen Oct 19, 2021
67eba13
Preparing for WINDOW_CORNER_RADIUS
batzen Oct 19, 2021
a957612
Fixing resizing when window is not active but resized using glow border
batzen Oct 19, 2021
716bc3d
Improving naming
batzen Oct 19, 2021
8998737
Moving ChangeScope to separate file
batzen Oct 21, 2021
1ea1bc3
Adding IGlowWindow to ease swapping implementations in the future
batzen Oct 21, 2021
a653a7c
Adding support for glow window title
batzen Oct 21, 2021
f14cfaa
Improving performance by reducing GetDC calls
batzen Oct 21, 2021
e88cd03
Improving performance by using handles directly
batzen Oct 21, 2021
ad2ab7e
Improving performance
batzen Oct 21, 2021
8069ec4
CreateCompatibleDC might return null
batzen Oct 21, 2021
9648d05
Code cleanup
batzen Oct 22, 2021
eae2ef2
Reducing allocations by removing linq
batzen Oct 22, 2021
3e7b2b6
Merge remote-tracking branch 'origin/develop' into features/Win11With…
batzen Oct 22, 2021
1068c2b
Improving performance by using DeferWindowPos
batzen Oct 22, 2021
ed5de4d
We also have to delay position updates when window is moved
batzen Oct 22, 2021
2ae29e4
Improving showcase
batzen Oct 23, 2021
57423c8
Removing TryToBeFlickerFree as it's no longer needed
batzen Oct 23, 2021
1a54050
Improving showcase
batzen Oct 23, 2021
774e4b2
Improving showcase
batzen Oct 23, 2021
d13d6c9
Adding missing SWP entry
batzen Oct 23, 2021
b7674bf
Fixing issues with TopMost and child windows
batzen Oct 23, 2021
76acf95
Making code easier to read
batzen Oct 23, 2021
a074419
Using generic Marshal methods
batzen Oct 23, 2021
aa4c416
Fixing base type for style enums
batzen Oct 24, 2021
b4d0b43
Preventing multiple dispose
batzen Oct 24, 2021
caf06e4
Changing calls to use delayIfNecessary=true
batzen Oct 24, 2021
a6945e6
Improving ToString
batzen Oct 24, 2021
2ba1d35
Improving trace output
batzen Oct 24, 2021
c8f391d
Adding keyboard shortcut to open child window
batzen Oct 24, 2021
c136966
Starting to transfer options to child windows
batzen Oct 24, 2021
061281b
Adding IsGlowTransitionEnabled to showcase
batzen Oct 24, 2021
0ea0467
Using factory method to create new windows
batzen Oct 24, 2021
d412639
We don't have to defer glow creation anymore
batzen Oct 24, 2021
cc8d616
We don't have to maintain Z-Order manually anymore
batzen Oct 24, 2021
d9d60bd
Small improvements to sizing and showing/hiding
batzen Oct 25, 2021
b8426f5
Adding ToString for WINDOWPLACEMENT
batzen Oct 25, 2021
98c217b
Making code easier to read
batzen Oct 25, 2021
74a0086
Fixing comment
batzen Oct 25, 2021
527b6fa
Adding DC to allowed abbreviations
batzen Oct 25, 2021
5d95405
Playground for window effects (acrylic, mica etc.)
batzen Oct 27, 2021
9c52d7d
Fixes #119 by using a point for the taskbar location and not a hwnd
batzen Oct 27, 2021
b8e2fed
Fixes #139
batzen Oct 27, 2021
3ddc049
Preventing restarts of timer
batzen Oct 27, 2021
6605c69
Prevent glow from getting visible before the owner/parent is visible
batzen Oct 27, 2021
47fd1f7
We have to use value source instead of local value
batzen Dec 6, 2021
b4b315f
We have to do input hit test instead of hit test to skip invisible el…
batzen Dec 6, 2021
66ff2ce
We have to clear the tracked NC item if window gets inactive
batzen Dec 6, 2021
195804a
We also have to set the composition background to make Mica etc. work
batzen Dec 6, 2021
30b0b07
Increasing resize area inside the window
batzen Dec 6, 2021
737ab34
Partially fixing detection of mouse moving off the window
batzen Dec 6, 2021
57e9c84
Adding native TrackMouseEvent things
batzen Dec 7, 2021
d9c6b6d
We only have to apply the edge fix for certain hittest results
batzen Dec 7, 2021
d633003
We have to track mouse events to get notifications on window leave
batzen Dec 7, 2021
e649322
Increasing version to 6.0
batzen Dec 7, 2021
eca09c2
Downgrading GitVersion to 5.6.3
batzen Dec 7, 2021
999b1e1
Upgrading GitVersion
batzen Dec 8, 2021
c958a03
Trying to fix GitVersion...
batzen Dec 8, 2021
80759f4
Merge branch 'develop' into features/Win11WithNewGlow
batzen Dec 8, 2021
e14960f
Trying to fix GitVersion...
batzen Dec 8, 2021
a5c9485
Trying to fix GitVersion...
batzen Dec 8, 2021
11563ff
Trying to fix activation issue on minimize
batzen Dec 9, 2021
b633f06
Adding NC to abbreviations
batzen Dec 11, 2021
e95219c
Removing comment
batzen Dec 11, 2021
c304617
Moving classes
batzen Dec 13, 2021
e85b109
Using EnsureHandle instead of relying on OnSourceInitialized
batzen Dec 13, 2021
dca7d0c
Moving WindowChromeWindow from showcase to library
batzen Dec 13, 2021
d2c6631
Removing support for .NET 4.5.2
batzen Dec 26, 2021
7904c59
Adding gitversion to solution files
batzen Dec 26, 2021
03575ae
Upgrading to .NET 6 SDK
batzen Jan 3, 2022
14efc15
Making use of SuppressRedrawScope
batzen Jan 3, 2022
b813577
Disabling tracing
batzen Jan 8, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ artifacts/
*.tlh
*.tmp
*.tmp_proj
*_wpftmp.csproj
*.log
*.binlog
*.vspscc
Expand Down
2 changes: 1 addition & 1 deletion GitVersion.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
assembly-versioning-scheme: Major
assembly-file-versioning-scheme: MajorMinorPatchTag
next-version: 5.0.0
next-version: 6.0.0
mode: ContinuousDeployment
branches:
master:
Expand Down
5 changes: 3 additions & 2 deletions appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,15 @@ environment:
secure: CUpRJxMLeUZwNPMcqI0wECaWfy5AMnWn1UZhBd9WnQ3Z16lJP1Vzrkf24mccbhUD
azure-key-vault-certificate:
secure: BSPdW2TgnQtoQXXbeDECug==
IGNORE_NORMALISATION_GIT_HEAD_MOVE: 1

skip_tags: true
image: Visual Studio 2019 Preview
image: Visual Studio 2022
test: off

install:
- ps: Invoke-WebRequest 'https://dot.net/v1/dotnet-install.ps1' -OutFile 'dotnet-install.ps1'
- ps: ./dotnet-install.ps1 -Version 5.0.103 -InstallDir "C:\Program Files\dotnet"
- ps: ./dotnet-install.ps1 -Version 6.0.100 -InstallDir "C:\Program Files\dotnet"

pull_requests:
do_not_increment_build_number: false
Expand Down
6 changes: 3 additions & 3 deletions build.cake
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
#tool dotnet:?package=NuGetKeyVaultSignTool&version=1.2.28
#tool dotnet:?package=AzureSignTool&version=2.0.17
#tool dotnet:?package=GitReleaseManager.Tool&version=0.12.0
#tool dotnet:?package=GitVersion.Tool&version=5.7.0
#tool dotnet:?package=GitVersion.Tool&version=5.6.3

#addin nuget:?package=Cake.Figlet&version=1.4.0

Expand All @@ -28,9 +28,9 @@ var isLocal = BuildSystem.IsLocalBuild;
// Set build version
if (isLocal == false || verbosity == Verbosity.Verbose)
{
GitVersion(new GitVersionSettings { OutputType = GitVersionOutput.BuildServer });
GitVersion(new GitVersionSettings { OutputType = GitVersionOutput.BuildServer, NoFetch = true });
}
GitVersion gitVersion = GitVersion(new GitVersionSettings { OutputType = GitVersionOutput.Json });
GitVersion gitVersion = GitVersion(new GitVersionSettings { OutputType = GitVersionOutput.Json, NoFetch = true });

var isPullRequest = AppVeyor.Environment.PullRequest.IsPullRequest;
var branchName = gitVersion.BranchName;
Expand Down
52 changes: 29 additions & 23 deletions src/ControlzEx.Showcase/App.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,38 +3,43 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:ControlzEx.Showcase"
xmlns:theming="clr-namespace:ControlzEx.Showcase.Theming"
StartupUri="MainWindow.xaml">
xmlns:controlzEx="urn:controlzex"
StartupUri="MainWindow.xaml"
ShutdownMode="OnMainWindowClose">
<Application.Resources>
<ResourceDictionary>
<theming:ShowcaseLibraryThemeProvider x:Key="{x:Static theming:ShowcaseLibraryThemeProvider.DefaultInstance}" />
<theming:SecondShowcaseLibraryThemeProvider x:Key="{x:Static theming:SecondShowcaseLibraryThemeProvider.DefaultInstance}" />

<Style x:Key="{x:Type local:WindowChromeWindow}" TargetType="{x:Type local:WindowChromeWindow}">
<SolidColorBrush x:Key="Button.Static.Background" Color="#FFDDDDDD" />
<SolidColorBrush x:Key="Button.Static.Border" Color="#FF707070" />
<SolidColorBrush x:Key="Button.MouseOver.Background" Color="#FFBEE6FD" />
<SolidColorBrush x:Key="Button.MouseOver.Border" Color="#FF3C7FB1" />
<SolidColorBrush x:Key="Button.Pressed.Background" Color="#FFC4E5F6" />
<SolidColorBrush x:Key="Button.Pressed.Border" Color="#FF2C628B" />
<SolidColorBrush x:Key="Button.Disabled.Background" Color="#FFF4F4F4" />
<SolidColorBrush x:Key="Button.Disabled.Border" Color="#FFADB2B5" />
<SolidColorBrush x:Key="Button.Disabled.Foreground" Color="#FF838383" />

<Style x:Key="{x:Type controlzEx:WindowChromeWindow}" TargetType="{x:Type controlzEx:WindowChromeWindow}">
<Setter Property="BorderThickness" Value="1" />
<Setter Property="BorderBrush" Value="{x:Null}" />
<Setter Property="NCActiveBrush" Value="{Binding Background, RelativeSource={RelativeSource Self}}" />
<Setter Property="NCCurrentBrush" Value="{Binding NCActiveBrush, RelativeSource={RelativeSource Self}}" />
<Setter Property="NCNonActiveBrush" Value="{Binding Source={x:Static SystemColors.WindowFrameBrush}}" />
<Setter Property="ResizeBorderThickness" Value="8" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:WindowChromeWindow}">
<ControlTemplate TargetType="{x:Type controlzEx:WindowChromeWindow}">
<Grid Background="{TemplateBinding Background}">
<AdornerDecorator>
<ContentPresenter />
</AdornerDecorator>

<Border x:Name="PART_Border2"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Background="{x:Null}"
BorderThickness="{TemplateBinding BorderThickness}"
UseLayoutRounding="True" />

<Border x:Name="PART_Border"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Background="{x:Null}"
BorderBrush="{TemplateBinding GlowBrush}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
UseLayoutRounding="True" />

Expand All @@ -45,13 +50,6 @@
Visibility="Collapsed" />
</Grid>
<ControlTemplate.Triggers>
<!-- handle active/inactive state -->
<Trigger Property="IsActive" Value="False">
<Setter TargetName="PART_Border" Property="BorderBrush" Value="{Binding Path=NonActiveGlowBrush, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}" />
</Trigger>
<Trigger SourceName="PART_Border" Property="BorderBrush" Value="{x:Null}">
<Setter TargetName="PART_Border2" Property="BorderBrush" Value="Black" />
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="Window.ResizeMode" Value="CanResizeWithGrip" />
Expand Down Expand Up @@ -81,10 +79,18 @@
</Style.Triggers>
</Style>

<Style x:Key="NoneWindowStyle"
BasedOn="{StaticResource {x:Type local:WindowChromeWindow}}"
TargetType="{x:Type local:WindowChromeWindow}">
<Setter Property="WindowStyle" Value="None" />
<Style x:Key="WindowTitleBarButton"
TargetType="Button">
<Style.Triggers>
<Trigger Property="controlzEx:NonClientControlProperties.IsNCMouseOver" Value="true">
<Setter Property="Background" Value="{StaticResource Button.MouseOver.Background}" />
<Setter Property="BorderBrush" Value="{StaticResource Button.MouseOver.Border}" />
</Trigger>
<Trigger Property="controlzEx:NonClientControlProperties.IsNCPressed" Value="true">
<Setter Property="Background" Value="{StaticResource Button.Pressed.Background}" />
<Setter Property="BorderBrush" Value="{StaticResource Button.Pressed.Border}" />
</Trigger>
</Style.Triggers>
</Style>
</ResourceDictionary>
</Application.Resources>
Expand Down
233 changes: 233 additions & 0 deletions src/ControlzEx.Showcase/Controls/UniformGridEx.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,233 @@
namespace ControlzEx.Showcase
{
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;

public class UniformGridEx : Panel
{
public static readonly DependencyProperty FirstColumnProperty = DependencyProperty.Register(nameof(FirstColumn), typeof(int), typeof(UniformGridEx), new FrameworkPropertyMetadata(0, FrameworkPropertyMetadataOptions.AffectsMeasure), ValidateFirstColumn);
public static readonly DependencyProperty ColumnsProperty = DependencyProperty.Register(nameof(Columns), typeof(int), typeof(UniformGridEx), new FrameworkPropertyMetadata(0, FrameworkPropertyMetadataOptions.AffectsMeasure), ValidateColumns);
public static readonly DependencyProperty RowsProperty = DependencyProperty.Register(nameof(Rows), typeof(int), typeof(UniformGridEx), new FrameworkPropertyMetadata(0, FrameworkPropertyMetadataOptions.AffectsMeasure), ValidateRows);
public static readonly DependencyProperty ShowGridLinesProperty = DependencyProperty.Register(nameof(ShowGridLines), typeof(bool), typeof(UniformGridEx), new FrameworkPropertyMetadata(false, OnShowGridLinesChanged));
public static readonly DependencyProperty GridLinesRendererProperty = DependencyProperty.Register(nameof(GridLinesRenderer), typeof(GridLinesRendererBase), typeof(UniformGridEx), new PropertyMetadata(default(UniformGridGridLinesRenderer), OnGridLinesRendererChanged));

private int columns;
private int rows;

public int FirstColumn
{
get => (int)this.GetValue(FirstColumnProperty);
set => this.SetValue(FirstColumnProperty, value);
}

public int Columns
{
get => (int)this.GetValue(ColumnsProperty);
set => this.SetValue(ColumnsProperty, value);
}

public int Rows
{
get => (int)this.GetValue(RowsProperty);
set => this.SetValue(RowsProperty, value);
}

public bool ShowGridLines
{
get => (bool)this.GetValue(ShowGridLinesProperty);
set => this.SetValue(ShowGridLinesProperty, value);
}

public GridLinesRendererBase GridLinesRenderer
{
get => (GridLinesRendererBase)this.GetValue(GridLinesRendererProperty);
set => this.SetValue(GridLinesRendererProperty, value);
}

protected override int VisualChildrenCount => base.VisualChildrenCount + (this.GridLinesRenderer is not null ? 1 : 0);

private static bool ValidateFirstColumn(object o)
{
return (int)o >= 0;
}

private static bool ValidateColumns(object o)
{
return (int)o >= 0;
}

private static bool ValidateRows(object o)
{
return (int)o >= 0;
}

protected override Visual GetVisualChild(int index)
{
if (index != base.VisualChildrenCount)
{
return base.GetVisualChild(index);
}

return this.GridLinesRenderer is not null
? (Visual)this.GridLinesRenderer
: throw new ArgumentOutOfRangeException(nameof(index), index, null);
}

protected override Size MeasureOverride(Size constraint)
{
this.UpdateComputedValues();

var availableSize = new Size(constraint.Width / this.columns, constraint.Height / this.rows);
var minChildWidth = 0.0;
var minChildHeight = 0.0;
var index = 0;

for (var count = this.InternalChildren.Count; index < count; ++index)
{
var internalChild = this.InternalChildren[index];
internalChild.Measure(availableSize);
var desiredSize = internalChild.DesiredSize;

if (minChildWidth < desiredSize.Width)
{
minChildWidth = desiredSize.Width;
}

if (minChildHeight < desiredSize.Height)
{
minChildHeight = desiredSize.Height;
}
}

return new Size(minChildWidth * this.columns, minChildHeight * this.rows);
}

protected override Size ArrangeOverride(Size arrangeSize)
{
var finalRect = new Rect(0.0, 0.0, arrangeSize.Width / this.columns, arrangeSize.Height / this.rows);
var columnWidth = finalRect.Width;
var rowHeight = finalRect.Height;
var adjustedWidth = arrangeSize.Width - 1.0;

finalRect.X += finalRect.Width * this.FirstColumn;

foreach (UIElement internalChild in this.InternalChildren)
{
internalChild.Arrange(finalRect);

if (internalChild.Visibility != Visibility.Collapsed)
{
finalRect.X += columnWidth;

if (finalRect.X >= adjustedWidth)
{
finalRect.Y += finalRect.Height;
finalRect.X = 0.0;
}
}
}

this.EnsureGridLinesRenderer()?.UpdateRenderBounds(arrangeSize, this.columns, columnWidth, this.rows, rowHeight);

return arrangeSize;
}

private void UpdateComputedValues()
{
this.columns = this.Columns;
this.rows = this.Rows;

if (this.FirstColumn >= this.columns)
{
this.FirstColumn = 0;
}

if (this.rows != 0
&& this.columns != 0)
{
return;
}

var visibleChildrenCount = 0;
var index = 0;
for (var count = this.InternalChildren.Count; index < count; ++index)
{
if (this.InternalChildren[index].Visibility != Visibility.Collapsed)
{
++visibleChildrenCount;
}
}

if (visibleChildrenCount == 0)
{
visibleChildrenCount = 1;
}

if (this.rows == 0)
{
if (this.columns > 0)
{
this.rows = (visibleChildrenCount + this.FirstColumn + (this.columns - 1)) / this.columns;
}
else
{
this.rows = (int)Math.Sqrt(visibleChildrenCount);
if (this.rows * this.rows < visibleChildrenCount)
{
++this.rows;
}

this.columns = this.rows;
}
}
else
{
if (this.columns != 0)
{
return;
}

this.columns = (visibleChildrenCount + (this.rows - 1)) / this.rows;
}
}

private GridLinesRendererBase EnsureGridLinesRenderer()
{
if (this.ShowGridLines)
{
this.GridLinesRenderer ??= this.CreateGridLinesRenderer();

if (this.GridLinesRenderer.Parent != this)
{
this.AddVisualChild(this.GridLinesRenderer);
}
}
else if (this.ShowGridLines == false
&& this.GridLinesRenderer is not null)
{
this.RemoveVisualChild(this.GridLinesRenderer);
}

return this.GridLinesRenderer;
}

protected virtual GridLinesRendererBase CreateGridLinesRenderer()
{
return new UniformGridGridLinesRenderer();
}

private static void OnShowGridLinesChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var grid = (UniformGridEx)d;
grid.InvalidateVisual();
}

private static void OnGridLinesRendererChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var grid = (UniformGridEx)d;
grid.InvalidateVisual();
}
}
}
Loading