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
3 changes: 3 additions & 0 deletions components/Behaviors/OpenSolution.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
@ECHO OFF

powershell ..\..\tooling\ProjectHeads\GenerateSingleSampleHeads.ps1 -componentPath %CD% %*
16 changes: 16 additions & 0 deletions components/Behaviors/samples/AutoSelectBehaviorSample.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<Page x:Class="BehaviorsExperiment.Samples.AutoSelectBehaviorSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:behaviors="using:CommunityToolkit.WinUI.Behaviors"
xmlns:interactivity="using:Microsoft.Xaml.Interactivity">

<StackPanel Padding="8"
Spacing="8">
<TextBox Text="My content is not selected when loaded" />
<TextBox Text="My content is selected when loaded">
<interactivity:Interaction.Behaviors>
<behaviors:AutoSelectBehavior />
</interactivity:Interaction.Behaviors>
</TextBox>
</StackPanel>
</Page>
16 changes: 16 additions & 0 deletions components/Behaviors/samples/AutoSelectBehaviorSample.xaml.cs
Original file line number Diff line number Diff line change
@@ -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 CommunityToolkit.WinUI.Behaviors;

namespace BehaviorsExperiment.Samples;

[ToolkitSample(id: nameof(AutoSelectBehaviorSample), nameof(AutoSelectBehavior), description: $"A sample for showing how to use the AutoSelectBehavior.")]
public sealed partial class AutoSelectBehaviorSample : Page
{
public AutoSelectBehaviorSample()
{
this.InitializeComponent();
}
}
8 changes: 8 additions & 0 deletions components/Behaviors/samples/Behaviors.Samples.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<Project Sdk="MSBuild.Sdk.Extras/3.0.23">
<PropertyGroup>
<ToolkitComponentName>Behaviors</ToolkitComponentName>
</PropertyGroup>

<!-- Sets this up as a toolkit component's sample project -->
<Import Project="$(ToolingDirectory)\ToolkitComponent.SampleProject.props" />
</Project>
47 changes: 47 additions & 0 deletions components/Behaviors/samples/Behaviors.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
---
title: Behaviors
author: Arlodotexe
description:
keywords: Behaviors
dev_langs:
- csharp
category: Xaml
subcategory: Behaviors
discussion-id: 0
issue-id: 0
---

# Behaviors

A behavior is a class that attaches to a XAML control and invokes an Action when triggered.

The `Microsoft.Xaml.Behaviors.*` packages contains several useful triggers and actions, and the Windows Community Toolkit provides even more.

See also [XamlBehaviors Wiki](https://github.com/Microsoft/XamlBehaviors/wiki)

## KeyDownTriggerBehavior

A behavior that listens to a key press event on the associated UIElement and triggers the set of actions.

> [!Sample KeyDownTriggerBehaviorSample]

## AutoSelectBehavior

The AutoSelectBehavior automatically selects the entire content of its associated TextBox when it is loaded.

> [!Sample AutoSelectBehaviorSample]

## ViewportBehavior
This behavior allows you to listen an element enter or exit the ScrollViewer viewport.

> [!Sample ViewportBehaviorSample]

## FocusBehavior

Of the given targets, this behavior sets the focus on the first control which accepts it.

A control only receives focus if it is enabled and loaded into the visual tree:
> [!Sample FocusBehaviorButtonSample]

Empty lists do not receive focus:
> [!Sample FocusBehaviorListSample]
31 changes: 31 additions & 0 deletions components/Behaviors/samples/Dependencies.props
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<!--
WinUI 2 under UWP uses TargetFramework uap10.0.*
WinUI 3 under WinAppSdk uses TargetFramework net6.0-windows10.*
However, under Uno-powered platforms, both WinUI 2 and 3 can share the same TargetFramework.

MSBuild doesn't play nicely with this out of the box, so we've made it easy for you.

For .NET Standard packages, you can use the Nuget Package Manager in Visual Studio.
For UWP / WinAppSDK / Uno packages, place the package references here.
-->
<Project>
<!-- WinUI 2 / UWP -->
<ItemGroup Condition="'$(IsUwp)' == 'true'">
<!-- <PackageReference Include="Microsoft.Toolkit.Uwp.UI.Controls.Primitives" Version="7.1.2"/> -->
</ItemGroup>

<!-- WinUI 2 / Uno -->
<ItemGroup Condition="'$(IsUno)' == 'true' AND '$(WinUIMajorVersion)' == '2'">
<!-- <PackageReference Include="Uno.Microsoft.Toolkit.Uwp.UI.Controls.Primitives" Version="7.1.11"/> -->
</ItemGroup>

<!-- WinUI 3 / WinAppSdk -->
<ItemGroup Condition="'$(IsWinAppSdk)' == 'true'">
<!-- <PackageReference Include="CommunityToolkit.WinUI.UI.Controls.Primitives" Version="7.1.2"/> -->
</ItemGroup>

<!-- WinUI 3 / Uno -->
<ItemGroup Condition="'$(IsUno)' == 'true' AND '$(WinUIMajorVersion)' == '3'">
<!-- <PackageReference Include="Uno.CommunityToolkit.WinUI.UI.Controls.Primitives" Version="7.1.100-dev.15.g12261e2626"/> -->
</ItemGroup>
</Project>
24 changes: 24 additions & 0 deletions components/Behaviors/samples/FocusBehaviorButtonSample.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<Page x:Class="BehaviorsExperiment.Samples.FocusBehaviorButtonSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:behaviors="using:CommunityToolkit.WinUI.Behaviors"
xmlns:interactivity="using:Microsoft.Xaml.Interactivity">

<interactivity:Interaction.Behaviors>
<behaviors:FocusBehavior>
<behaviors:FocusTarget Control="{x:Bind ButtonOne}" />
<behaviors:FocusTarget Control="{x:Bind ButtonTwo}" />
</behaviors:FocusBehavior>
</interactivity:Interaction.Behaviors>

<StackPanel Spacing="12">
<Button x:Name="ButtonOne"
x:Load="{x:Bind ControlLoaded, Mode=OneWay}"
Content="Button One"
IsEnabled="{x:Bind IsButtonEnabled, Mode=OneWay}" />

<Button x:Name="ButtonTwo"
Content="Button Two" />
</StackPanel>

</Page>
18 changes: 18 additions & 0 deletions components/Behaviors/samples/FocusBehaviorButtonSample.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// 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 CommunityToolkit.WinUI.Behaviors;

namespace BehaviorsExperiment.Samples;

[ToolkitSampleBoolOption("IsButtonEnabled", true, Title = "Enable button")]
[ToolkitSampleBoolOption("ControlLoaded", true, Title = "Toggle x:Bind")]
[ToolkitSample(id: nameof(FocusBehaviorButtonSample), $"{nameof(FocusBehavior)}: Disabled / Unloaded items", description: $"A sample demonstrating how {nameof(FocusBehavior)} affects disabled or unloaded controls.")]
public sealed partial class FocusBehaviorButtonSample : Page
{
public FocusBehaviorButtonSample()
{
this.InitializeComponent();
}
}
25 changes: 25 additions & 0 deletions components/Behaviors/samples/FocusBehaviorListSample.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<Page x:Class="BehaviorsExperiment.Samples.FocusBehaviorListSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:behaviors="using:CommunityToolkit.WinUI.Behaviors"
xmlns:interactivity="using:Microsoft.Xaml.Interactivity">

<interactivity:Interaction.Behaviors>
<behaviors:FocusBehavior>
<behaviors:FocusTarget Control="{x:Bind EmptyList}" />
<behaviors:FocusTarget Control="{x:Bind NonEmptyList}" />
</behaviors:FocusBehavior>
</interactivity:Interaction.Behaviors>

<StackPanel>
<ListView x:Name="EmptyList" />

<ListView x:Name="NonEmptyList">
<ListView.Items>
<x:String>Item 1</x:String>
<x:String>Item 2</x:String>
</ListView.Items>
</ListView>
</StackPanel>

</Page>
16 changes: 16 additions & 0 deletions components/Behaviors/samples/FocusBehaviorListSample.xaml.cs
Original file line number Diff line number Diff line change
@@ -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 CommunityToolkit.WinUI.Behaviors;

namespace BehaviorsExperiment.Samples;

[ToolkitSample(id: nameof(FocusBehaviorListSample), $"{nameof(FocusBehavior)}: Lists", description: $"A sample demonstrating how {nameof(FocusBehavior)} affects lists.")]
public sealed partial class FocusBehaviorListSample : Page
{
public FocusBehaviorListSample()
{
this.InitializeComponent();
}
}
25 changes: 25 additions & 0 deletions components/Behaviors/samples/KeyDownTriggerBehaviorSample.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<Page x:Class="BehaviorsExperiment.Samples.KeyDownTriggerBehaviorSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:behaviors="using:CommunityToolkit.WinUI.Behaviors"
xmlns:core="using:Microsoft.Xaml.Interactions.Core"
xmlns:interactivity="using:Microsoft.Xaml.Interactivity">

<StackPanel Padding="12"
Spacing="8">
<TextBox PlaceholderText="Set the focus to this TextBox and press enter">
<interactivity:Interaction.Behaviors>
<behaviors:KeyDownTriggerBehavior Key="Enter">
<core:CallMethodAction MethodName="IncrementCount"
TargetObject="{x:Bind}" />
</behaviors:KeyDownTriggerBehavior>
</interactivity:Interaction.Behaviors>
</TextBox>

<TextBlock>
<Run Text="Enter pressed" />
<Run Text="{x:Bind Count, Mode=OneWay}" />
<Run Text="times." />
</TextBlock>
</StackPanel>
</Page>
26 changes: 26 additions & 0 deletions components/Behaviors/samples/KeyDownTriggerBehaviorSample.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// 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 CommunityToolkit.WinUI.Behaviors;

namespace BehaviorsExperiment.Samples;

[ToolkitSample(id: nameof(KeyDownTriggerBehaviorSample), nameof(KeyDownTriggerBehavior), description: $"A sample for showing how to use the {nameof(KeyDownTriggerBehavior)}.")]
public sealed partial class KeyDownTriggerBehaviorSample : Page, INotifyPropertyChanged
{
public KeyDownTriggerBehaviorSample()
{
this.InitializeComponent();
}

public int Count { get; set; }

public void IncrementCount()
{
Count++;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Count)));
}

public event PropertyChangedEventHandler? PropertyChanged;
}
58 changes: 58 additions & 0 deletions components/Behaviors/samples/ViewportBehaviorSample.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<Page x:Class="BehaviorsExperiment.Samples.ViewportBehaviorSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:behaviors="using:CommunityToolkit.WinUI.Behaviors"
xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
x:Name="RootElement">

<Grid Padding="12">

<Grid MaxWidth="500"
MaxHeight="500"
BorderBrush="#55000000"
BorderThickness="2">

<TextBlock Padding="8"
HorizontalAlignment="Center"
Foreground="OrangeRed"
IsHitTestVisible="False"
Text="Scroll to see the effect" />

<ScrollViewer>
<Grid Height="3000">
<Border Width="200"
Height="200"
Background="Gray">

<interactivity:Interaction.Behaviors>
<behaviors:ViewportBehavior x:Name="ViewportBehavior"
IsAlwaysOn="{x:Bind IsAlwaysOn, Mode=OneWay}" />
</interactivity:Interaction.Behaviors>

<Rectangle Width="100"
Height="100"
Fill="Red" />
</Border>
</Grid>
</ScrollViewer>

<StackPanel Padding="12"
HorizontalAlignment="Right"
VerticalAlignment="Bottom"
Background="#55000000">
<TextBlock>
<Run Foreground="#75FFFFFF"
Text="IsFullyInViewport:" />
<Run Text="{x:Bind ViewportBehavior.IsFullyInViewport, Mode=OneWay}" />
</TextBlock>

<TextBlock>
<Run Foreground="#75FFFFFF"
Text="IsInViewport:" />
<Run Text="{x:Bind ViewportBehavior.IsInViewport, Mode=OneWay}" />
</TextBlock>
</StackPanel>
</Grid>

</Grid>
</Page>
17 changes: 17 additions & 0 deletions components/Behaviors/samples/ViewportBehaviorSample.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// 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 CommunityToolkit.WinUI.Behaviors;

namespace BehaviorsExperiment.Samples;

[ToolkitSampleBoolOption("IsAlwaysOn", true, Title = "IsAlwaysOn")]
[ToolkitSample(id: nameof(ViewportBehaviorSample), nameof(ViewportBehavior), description: $"A sample for showing how to use the {nameof(ViewportBehavior)}.")]
public sealed partial class ViewportBehaviorSample : Page
{
public ViewportBehaviorSample()
{
this.InitializeComponent();
}
}
13 changes: 13 additions & 0 deletions components/Behaviors/src/AdditionalAssemblyInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// 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 System.Runtime.CompilerServices;

// These `InternalsVisibleTo` calls are intended to make it easier for
// for any internal code to be testable in all the different test projects
// used with the Labs infrastructure.
[assembly: InternalsVisibleTo("Behaviors.Tests.Uwp")]
[assembly: InternalsVisibleTo("Behaviors.Tests.WinAppSdk")]
[assembly: InternalsVisibleTo("CommunityToolkit.Tests.Uwp")]
[assembly: InternalsVisibleTo("CommunityToolkit.Tests.WinAppSdk")]
13 changes: 13 additions & 0 deletions components/Behaviors/src/ApiInformationHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// 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.Foundation.Metadata;

namespace CommunityToolkit.WinUI.Behaviors;

internal class ApiInformationHelper
{
// 1903 - 18362
public static bool IsXamlRootAvailable { get; } = ApiInformation.IsPropertyPresent("Windows.UI.Xaml.UIElement", "XamlRoot");
}
Loading