Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
7 changes: 5 additions & 2 deletions docs/.template.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,12 @@ dev_langs:
- csharp
---

<!-- To know about all the available Markdown syntax, Check out https://docs.microsoft.com/contribute/contribute/how-to-write-use-markdown -->
<!-- To know about all the available Markdown syntax, Check out https://docs.microsoft.com/en-us/contribute/markdown-reference -->
<!-- Ensure you remove all comments before submission, to ensure that there are no formatting issues when displaying this page. -->
<!-- It is recommended to check how the Documentation will look in the sample app, before Merging a PR -->
<!-- **Note:** All links to other docs.microsoft.com pages should be relative without locale, i.e. for the one above would be /contribute/markdown-reference -->
<!-- Included images should be optimized for size and not include any Intellectual Property references. -->
<!-- When linking to the Community Toolkit repo for source references include the specific rel/#.#.# version path of the expected release version, this ensures code will be accessible by docs if it is refactored or moved during development of the next release. -->

# Title

Expand All @@ -30,7 +33,7 @@ with the namespace and the class name. Without any country/region 'en-us' identi
> Some warning note
-->

> **Platform APIs:** Include a comma separated list of links of any APIs used in the document in the following format: [`Class/InterfaceName`](API-Link).
> **Platform APIs:** <!-- Include a comma separated list of links of any APIs used in the document in the following format: --> [`Class/InterfaceName`](API-Link)

<!-- If you have a sample app page, use the sample app category and the name from samples.json here: -->

Expand Down
58 changes: 58 additions & 0 deletions docs/controls/ConstrainedBox.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
---
title: ConstrainedBox
author: michael-hawker
description: Constrain a child element by aspect ratio, scale, or multiple.
keywords: windows 10, uwp, windows community toolkit, uwp community toolkit, uwp toolkit, viewbox, content decorator, ConstrainedBox
dev_langs:
- csharp
---

# ConstrainedBox

The [ConstrainedBox](/dotnet/api/microsoft.toolkit.uwp.ui.controls.constrainedbox) is a simple `FrameworkElement` content decorator control which allows the developer to constrain its child content by one or more various properties including aspect ratio, scale, and aligning to a multiple boundary.

> [!NOTE]
> For technical reasons this control inherits from `ContentPresenter`; however, it should be treated as a `FrameworkElement` and its border and template properties should not be used for compatibility in the future when it can inherit from FrameworkElement directly.

> **Platform APIs:** [`ConstrainedBox`](/dotnet/api/microsoft.toolkit.uwp.ui.controls.constrainedbox), [`AspectRatio`](/dotnet/api/microsoft.toolkit.uwp.ui.controls.aspectratio)

> [!div class="nextstepaction"]
> [Try it in the sample app](uwpct://controls?sample=constrainedbox)

The three constraints provided by the `ConstrainedBox` control can be used individually & independently or combined to provide a wide-variety of responsive layout options. When used in combination, for the properties used, they are always applied in the following order:

1. `ScaleX`/`ScaleY`: Scaling is applied first to restrict the overall available size in each axis from the parent container based on a percentage value from 0.0-1.0. The default value is 1.0 to use all available size.

2. `MultipleX`/`MultipleY`: The multiple values allow a developer to snap the layout size of the child to a specific multiple value. For instance, by providing a value of 4, you would ensure the child element is closest to the size of 16, 20, 24, etc... The floor is taken so the child element is always smaller within the bounds of its parent. By default this value is not set so that no extra layout rounding occurs.

3. `AspectRatio`: The aspect ratio can be provided by a double value or a colon separated aspect (e.g. "16:9") and will restrict the layout of the child element to that available space. Therefore if you stretch your child element you can ensure it maintains the desired aspect ratio. By default, no aspect ratio constraint is applied.

If a `ConstrainedBox` is placed in a container which doesn't restrict its size in both the horizontal and vertical directions, it will try to determine its constraints based on the desired size of its child element. If only one direction has infinite size, the control will attempt to use the fixed dimension to measure all constraints against.

The Min/Max and Alignment properties of the `ConstrainedBox` itself and its child can also be set to provide other constraints on how layout is performed with the control, as with any regular XAML layout.

## Example

The following example shows how to align a 16:9 view of an image with the top of its container (like a page) and center on the image's content:

```xaml
<controls:ConstrainedBox AspectRatio="16:9" VerticalAlignment="Top">
<Image Source="/Assets/Photos/WestSeattleView.jpg"
Stretch="UniformToFill"
VerticalAlignment="Center"/> <!-- Center viewport on image -->
</controls:ConstrainedBox>
```

## Sample Project

[ConstrainedBox sample page Source](https://github.com/CommunityToolkit/WindowsCommunityToolkit/blob/rel/7.1.0/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Primitives/ConstrainedBox.bind). You can [see this in action](uwpct://controls?sample=constrainedbox) in [Windows Community Toolkit Sample App](https://aka.ms/windowstoolkitapp).

## Source Code

- [ConstrainedBox source code](https://github.com/CommunityToolkit/WindowsCommunityToolkit/tree/rel/7.1.0/Microsoft.Toolkit.Uwp.UI.Controls.Primitives/ConstrainedBox)

## Related Topics

- [UseLayoutRounding](/uwp/api/windows.ui.xaml.uielement.uselayoutrounding)
- [FrameworkElement](/uwp/api/windows.ui.xaml.frameworkelement)
- [Viewbox](/uwp/api/windows.ui.xaml.controls.viewbox)
3 changes: 3 additions & 0 deletions docs/controls/DropShadowPanel.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ dev_langs:

# DropShadowPanel

> [!WARNING]
> This control has been deprecated in the Windows Community Toolkit and will be removed in a future release. Please use the new [Attached Shadow](../Helpers/AttachedShadows.md) helpers instead.

The [DropShadowPanel](/dotnet/api/microsoft.toolkit.uwp.ui.controls.dropshadowpanel) control allows the creation of a drop shadow effect for any Xaml FrameworkElement in the markup.

> [!div class="nextstepaction"]
Expand Down
174 changes: 174 additions & 0 deletions docs/helpers/AttachedShadows.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
---
title: Attached Shadows
author: michael-hawker
description: Attached Shadows allow you to easily create shadow effects on elements.
keywords: windows 10, uwp, windows community toolkit, uwp community toolkit, uwp toolkit, shadow, shadows, dropshadow, dropshadowpanel, attachedshadow, attacheddropshadow, attachedcardshadow
dev_langs:
- csharp
---

# Attached Shadows

Attached Shadows allow you to more easily create beautiful shadow effects within your app with little to no modification of the visual tree required, unlike our previous [`DropShadowPanel`](../controls/DropShadowPanel.md) control.

> **Platform APIs:** [`AttachedCardShadow`](/dotnet/api/microsoft.toolkit.uwp.ui.media.attachedcardshadow), [`AttachedDropShadow`](/dotnet/api/microsoft.toolkit.uwp.ui.attacheddropshadow)

## Introduction

There are two types of attached shadows available today, the `AttachedCardShadow` and the `AttachedDropShadow`. It is recommended to use the `AttachedCardShadow` where possible, if you don't mind the dependency on Win2D. The `AttachedCardShadow` provides an easier to use experience that is more performant and easier to apply across an entire set of elements, assuming those elements are rounded-rectangular in shape. The `AttachedDropShadow` provides masking support and can be leveraged in any UWP app without adding an extra dependency.

### Capability Comparison

The following table outlines the various capabilities of each shadow type in addition to comparing to the previous `DropShadowPanel` implementation:

| Capability | AttachedCardShadow | AttachedDropShadow | DropShadowPanel (deprecated) |
|-------------------------------|--------------------------------------------------------------------|-----------------------------------------------------------------|-----------------------------------------------------------------------------------------|
| Dependency/NuGet Package | 🟡 Win2D via<br>`Microsoft.Toolkit.Uwp.UI.Media` | ✅ UWP Only (Composition Effect)<br>`Microsoft.Toolkit.Uwp.UI` | ✅ UWP Only (Composition Effect)<br>`Microsoft.Toolkit.Uwp.UI` |
| Layer | Inline Composition +<br>Win2D Clip Geometry | Composition via<br>Target Element Backdrop | Composition via<br>`ContentControl` Container |
| Modify Visual Tree | ✅ No | 🟡 Usually requires single target element, even for multiple shadows | ❌ Individually wrap each element needing shadow |
| Extra Visual Tree Depth | ✅ 0 | 🟡 1 per sibling element to cast one or more shadows to | ❌ _**4** per Shadowed Element_ |
| Masking/Geometry | 🟡 Rectangular/Rounded-Rectangles only | ✅ Can mask images, text, and shapes (performance penalty) | ✅ Can mask images, text, and shapes (performance penalty) |
| Performance | ✅ Fast, applies rectangular clipped geometry | 🟡 Slower, especially when masking (default);<br>can use rounded-rectangles optimization | ❌ Slowest, no optimization for rounded-rectangles |
| ResourceDictionary Support | ✅ Yes | ✅ Yes | ❌ Limited, via complete custom control style +<br>still need to wrap each element to apply |
| Usable in Styles | ✅ Yes, anywhere, including app-level | 🟡 Yes, but limited in scope due to element target | ❌ No |
| Supports Transparent Elements | ✅ Yes, shadow is clipped and not visible | ❌ No, shadow shows through transparent element | ❌ No, shadow shows through transparent element |
| Animation Support | ✅ Yes, in XAML via [`AnimationSet`](../animations/AnimationSet.md) | 🟡 Partial, translating/moving element may desync shadow | ❌ No |

## AttachedCardShadow (Win2D)

The `AttachedCardShadow` is the easiest to use and most performant shadow. It is recommended to use it where possible, if taking a Win2D dependency is not a concern. It's only drawbacks are the extra dependency required and that it only supports rectangular and rounded-rectangular geometries (as described in the table above).

> [!div class="nextstepaction"]
> [Try it in the sample app](uwpct://controls?sample=attachedcardshadow%20%28win2d%29)

The great benefit to the `AttachedCardShadow` is that no extra surface or element is required to add the shadow. This reduces the complexity required in development and allows shadows to easily be added at any point in the development process. It also supports transparent elements, without displaying the shadow behind them!

### Example

The example shows how easy it is to not only apply an `AttachedCardShadow` to an element, but use it in a style to apply to multiple elements as well:

```xaml
xmlns:ui="using:Microsoft.Toolkit.Uwp.UI"
xmlns:media="using:Microsoft.Toolkit.Uwp.UI.Media"/>

<Page.Resources>
<media:AttachedCardShadow x:Key="CommonShadow" Offset="4"/>

<Style TargetType="Button" BasedOn="{StaticResource DefaultButtonStyle}">
<Setter Property="ui:Effects.Shadow" Value="{StaticResource CommonShadow}"/>
<Setter Property="HorizontalAlignment" Value="Center"/>
</Style>
</Page.Resources>

<StackPanel Spacing="32" VerticalAlignment="Center">
<Button Content="I Have a Shadow!"/>
<Image ui:Effects.Shadow="{StaticResource CommonShadow}"
Height="100" Width="100"
Source="ms-appx:///Assets/Photos/Owl.jpg"/>
</StackPanel>
```

### Example Output

![Card Shadow Examples](../resources/images/Helpers/Shadows/CardShadow.png)

## AttachedDropShadow (Composition)

The `AttachedDropShadow` provides masking support to a wide variety of elements including transparent images, shapes, and text. Masking to a custom shape that's not rectangular or rounded-rectangular is the main scenario where an `AttachedDropShadow` will be useful. Unlike it's predecessor, the [`DropShadowPanel`](../Controls/DropShadowPanel.md), the `AttachedDropShadow` doesn't need to wrap the element being shadowed; however, it does require another element to cast the shadow on to.

This makes it a bit more complex to use than the `AttachedCardShadow` and the `DropShadowPanel`, but since multiple `AttachedDropShadow` elements can share the same surface, this makes it much more performant than its predecessor.

> [!div class="nextstepaction"]
> [Try it in the sample app](uwpct://controls?sample=attacheddropshadow%20%28composition%29)

### Remarks

While `DropShadowPanel` encapsulated the complexities of adding a shadow, it added a lot of depth and complexity to the visual tree. `AttachedDropShadow` instead requires that you provide the surface where the shadows should be cast, such as a common backdrop element. This means that each shadow can use the same shared surface rather than creating its own backdrop element for each shadow (like `DropShadowPanel` did). This slight trade-off for ease-of-use is a gain in performance. However, it does mean it may not be as flexible for certain use cases with manipulation of an element. In those cases we recommend to try and use `AttachedCardShadow` instead or wrapping an element and its backdrop in a custom control.

### Example

The following example shows how to use an `AttachedDropShadow` as a resource with a `TextBlock` to mask the shadow of some text:

```xaml
<Page.Resources>
<ui:AttachedDropShadow x:Key="CommonShadow" Offset="4" CastTo="{x:Bind ShadowTarget}"/>
</Page.Resources>

<Grid>
<Border x:Name="ShadowTarget"/>
<TextBlock ui:Effects.Shadow="{StaticResource CommonShadow}"
Text="This is some text with a Shadow!"
HorizontalAlignment="Center"/>
</Grid>
```

### Example Output

![Text with Attached Shadow](../resources/images/Helpers/Shadows/TextShadow.png)

## Animation

Either type of Attached Shadow can be easily animated using the Toolkit's [`AnimationSet`](../animations/AnimationSet.md) api. These provide an easy XAML based way to animate a wide variety of elements, including a variety of shadow properties. They can also be animated with any other composition animation technique in code-behind as well using either the [`AnimationBuilder`](../animations/AnimationBuilder.md) or built-in composition animations.

> **Platform APIs:** [`BlurRadiusDropShadowAnimation`](/dotnet.api/microsoft.toolkit.uwp.ui.animations.blurradiusdropshadowanimation), [`ColorDropShadowAnimation`](/dotnet.api/microsoft.toolkit.uwp.ui.animations.colordropshadowanimation), [`OffsetDropShadowAnimation`](/dotnet.api/microsoft.toolkit.uwp.ui.animations.offsetdropshadowanimation), [`OpacityDropShadowAnimation`](/dotnet.api/microsoft.toolkit.uwp.ui.animations.opacitydropshadowanimation)

> [!NOTE]
> `AttachedCardShadow` has better support for animations which involve translation of the element along with the shadow. If animating an `AttachedDropShadow` it is best to only animate the shadow itself vs. moving the element it is attached to. This can cause the shadow and element to be desynchronized.

> [!div class="nextstepaction"]
> [Try it in the sample app](uwpct://animations?sample=shadow%20animations)

### Example

The following example uses a combination of behaviors and animations apis to create an animated shadow effect when hovering over an image with an [`OffsetDropShadowAnimation`](/dotnet.api/microsoft.toolkit.uwp.ui.animations.offsetdropshadowanimation):

```xaml
xmlns:ui="using:Microsoft.Toolkit.Uwp.UI"
xmlns:media="using:Microsoft.Toolkit.Uwp.UI.Media"
xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
xmlns:interactions="using:Microsoft.Xaml.Interactions.Core"
xmlns:ani="using:Microsoft.Toolkit.Uwp.UI.Animations"
xmlns:behaviors="using:Microsoft.Toolkit.Uwp.UI.Behaviors"/>

<Image Height="100" Width="100"
Source="ms-appx:///Assets/Photos/Owl.jpg">
<ui:Effects.Shadow>
<media:AttachedCardShadow Offset="4" CornerRadius="0"/>
</ui:Effects.Shadow>
<ani:Explicit.Animations>
<ani:AnimationSet x:Name="ShadowEnterAnimation">
<ani:OffsetDropShadowAnimation To="12"/>
</ani:AnimationSet>

<ani:AnimationSet x:Name="ShadowExitAnimation">
<ani:OffsetDropShadowAnimation To="4"/>
</ani:AnimationSet>
</ani:Explicit.Animations>
<interactivity:Interaction.Behaviors>
<interactions:EventTriggerBehavior EventName="PointerEntered">
<behaviors:StartAnimationAction Animation="{x:Bind ShadowEnterAnimation}"/>
</interactions:EventTriggerBehavior>
<interactions:EventTriggerBehavior EventName="PointerExited">
<behaviors:StartAnimationAction Animation="{x:Bind ShadowExitAnimation}"/>
</interactions:EventTriggerBehavior>
</interactivity:Interaction.Behaviors>
</Image>
```

### Example Output

![Image with popped shadow on hover](../resources/images/Helpers/Shadows/ShadowHover.gif)

## Sample Project

[Attached Shadows sample page Source](https://github.com/CommunityToolkit/WindowsCommunityToolkit/blob/rel/7.1.0/Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Shadows). You can [see this in action](uwpct://CategoryName?sample=pageName) in [Windows Community Toolkit Sample App](https://aka.ms/windowstoolkitapp).

## Source Code

- [AttachedCardShadow source code](https://github.com/CommunityToolkit/WindowsCommunityToolkit/blob/rel/7.1.0/Microsoft.Toolkit.Uwp.UI.Media/Shadows/AttachedCardShadow.cs)
- [AttachedDropShadow source code](https://github.com/CommunityToolkit/WindowsCommunityToolkit/tree/rel/7.1.0/Microsoft.Toolkit.Uwp.UI/Shadows)

## Related Topics

- [Composition Shadows](/windows/uwp/composition/composition-shadows)
- [DropShadow Class](/uwp/api/Windows.UI.Composition.DropShadow)
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions docs/toc.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,8 @@

### [ColorPickerButton](controls/ColorPicker.md)

### [ConstrainedBox](controls/ConstrainedBox.md)

### DataGrid

#### [Introduction](controls/DataGrid.md)
Expand Down Expand Up @@ -285,6 +287,8 @@

### [AdvancedCollectionView](helpers/AdvancedCollectionView.md)

### [Attached Shadows](helpers/AttachedShadows.md)

### [BackgroundTaskHelper](helpers/BackgroundTaskHelper.md)

### [BindableValueHolder](helpers/BindableValueHolder.md)
Expand Down