diff --git a/Microsoft.Toolkit.Uwp.SampleApp/Microsoft.Toolkit.Uwp.SampleApp.csproj b/Microsoft.Toolkit.Uwp.SampleApp/Microsoft.Toolkit.Uwp.SampleApp.csproj
index db67c3365e3..77be6020d17 100644
--- a/Microsoft.Toolkit.Uwp.SampleApp/Microsoft.Toolkit.Uwp.SampleApp.csproj
+++ b/Microsoft.Toolkit.Uwp.SampleApp/Microsoft.Toolkit.Uwp.SampleApp.csproj
@@ -512,6 +512,9 @@
EyedropperPage.xaml
+
+ ClipToBoundsPage.xaml
+
ImageExLazyLoadingControl.xaml
@@ -925,6 +928,13 @@
Designer
MSBuild:Compile
+
+ Designer
+
+
+ Designer
+ MSBuild:Compile
+
Designer
MSBuild:Compile
diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ClipToBounds/ClipToBoundsCode.bind b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ClipToBounds/ClipToBoundsCode.bind
new file mode 100644
index 00000000000..590a8f82be5
--- /dev/null
+++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ClipToBounds/ClipToBoundsCode.bind
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ClipToBounds/ClipToBoundsPage.xaml b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ClipToBounds/ClipToBoundsPage.xaml
new file mode 100644
index 00000000000..9e1fc882026
--- /dev/null
+++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ClipToBounds/ClipToBoundsPage.xaml
@@ -0,0 +1,13 @@
+
+
+
+
+
diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ClipToBounds/ClipToBoundsPage.xaml.cs b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ClipToBounds/ClipToBoundsPage.xaml.cs
new file mode 100644
index 00000000000..12c292a52a7
--- /dev/null
+++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/ClipToBounds/ClipToBoundsPage.xaml.cs
@@ -0,0 +1,16 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using Windows.UI.Xaml.Controls;
+
+namespace Microsoft.Toolkit.Uwp.SampleApp.SamplePages
+{
+ ///
+ /// A page that shows how to use the ClipToBounds extension.
+ ///
+ public sealed partial class ClipToBoundsPage : Page
+ {
+ public ClipToBoundsPage() => InitializeComponent();
+ }
+}
diff --git a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/samples.json b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/samples.json
index 22cef444cca..e7f77241fb6 100644
--- a/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/samples.json
+++ b/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/samples.json
@@ -1069,6 +1069,15 @@
"Icon": "/Assets/Helpers.png",
"DocumentationUrl": "https://raw.githubusercontent.com/MicrosoftDocs/WindowsCommunityToolkitDocs/master/docs/extensions/FrameworkElementExtensions.md"
},
+ {
+ "Name": "ClipToBounds",
+ "Type": "ClipToBoundsPage",
+ "About": "Extension to clip the UIElement inner controls inside its bounds.",
+ "CodeUrl": "https://github.com/windows-toolkit/WindowsCommunityToolkit/tree/master/Microsoft.Toolkit.Uwp.UI/Extensions/UIElement",
+ "XamlCodeFile": "ClipToBoundsCode.bind",
+ "Icon": "/Assets/Helpers.png",
+ "DocumentationUrl": "https://raw.githubusercontent.com/MicrosoftDocs/WindowsCommunityToolkitDocs/master/docs/extensions/UIElementExtensions.md"
+ },
{
"Name": "StringExtensions",
"Type": "StringExtensionsPage",
diff --git a/Microsoft.Toolkit.Uwp.UI/Extensions/UIElement/UIElementExtensions.cs b/Microsoft.Toolkit.Uwp.UI/Extensions/UIElement/UIElementExtensions.cs
new file mode 100644
index 00000000000..fb340484aa6
--- /dev/null
+++ b/Microsoft.Toolkit.Uwp.UI/Extensions/UIElement/UIElementExtensions.cs
@@ -0,0 +1,48 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using Windows.UI.Xaml;
+using Windows.UI.Xaml.Hosting;
+
+namespace Microsoft.Toolkit.Uwp.UI.Extensions
+{
+ ///
+ /// Provides attached dependency properties for the
+ ///
+ public static class UIElementExtensions
+ {
+ ///
+ /// Attached that indicates whether or not the contents of the target should always be clipped to their parent's bounds.
+ ///
+ public static readonly DependencyProperty ClipToBoundsProperty = DependencyProperty.RegisterAttached(
+ "ClipToBounds",
+ typeof(bool),
+ typeof(UIElementExtensions),
+ new PropertyMetadata(DependencyProperty.UnsetValue, OnClipToBoundsPropertyChanged));
+
+ ///
+ /// Gets the value of
+ ///
+ /// The to read the property value from
+ /// The associated with the .
+ public static bool GetClipToBounds(UIElement element) => (bool)element.GetValue(ClipToBoundsProperty);
+
+ ///
+ /// Sets the value of
+ ///
+ /// The to set the property to
+ /// The new value of the attached property
+ public static void SetClipToBounds(UIElement element, bool value) => element.SetValue(ClipToBoundsProperty, value);
+
+ private static void OnClipToBoundsPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
+ {
+ if (d is UIElement element)
+ {
+ var clipToBounds = (bool)e.NewValue;
+ var visual = ElementCompositionPreview.GetElementVisual(element);
+ visual.Clip = clipToBounds ? visual.Compositor.CreateInsetClip() : null;
+ }
+ }
+ }
+}