Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Port/extensions #12

Merged
merged 12 commits into from
Apr 4, 2023
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 Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<NoWarn>$(NoWarn);Uno0001</NoWarn>
<!-- TODO: Turn off sample pages needing samples for now, for initial commit -->
<NoWarn>$(NoWarn);TKSMPL0014</NoWarn>
</PropertyGroup>

<Import Project="Windows.Toolkit.Common.props" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// See the LICENSE file in the project root for more information.

// TODO: Need to better understand how this works/maps on Uno between Uno.UI/Uno.WinUI,
// This should be the equivelant code from Uno.WinUI from: https://github.com/unoplatform/Uno.WindowsCommunityToolkit/blob/uno/CommunityToolkit.WinUI.UI/Converters/ResourceNameToResourceStringConverter.cs
// This should be the equivalent code from Uno.WinUI from: https://github.com/unoplatform/Uno.WindowsCommunityToolkit/blob/uno/CommunityToolkit.WinUI.UI/Converters/ResourceNameToResourceStringConverter.cs
#if WINAPPSDK && !HAS_UNO
using Microsoft.Windows.ApplicationModel.Resources;
#else
Expand Down
3 changes: 3 additions & 0 deletions components/Extensions/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% %*
62 changes: 62 additions & 0 deletions components/Extensions/samples/ArrayExtensions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
---
title: Array Extensions
author: michael-hawker
description: Learn about array extension methods from the community toolkit. See code examples and view requirements.
keywords: windows 10, uwp, uwp community toolkit, uwp toolkit, Extensions, array
dev_langs:
- csharp
category: Extensions
subcategory: Math
discussion-id: 0
issue-id: 0
---

# Array Extensions

> [!WARNING]
> These extensions have been partially moved to the `Microsoft.Toolkit.HighPerformance` package. Please refer to the .NET API browser for a comprehensive list of available APIs.

Provides a few helpers for dealing with multidimensional and jagged arrays. Also, provides string helpers for debug output.

## Syntax

```csharp
using Microsoft.Toolkit.Extensions;

bool[,] inside = new bool[4, 5];

// Fill the inside of the boolean array with 'true' values.
inside.Fill(true, 1, 1, 3, 2);

Debug.WriteLine(inside.ToArrayString());

/*
Output:
[[False, False, False, False, False],
[False, True, True, True, False],
[False, True, True, True, False],
[False, False, False, False, False]]
*/
```

## Methods

| Methods | Return Type | Description |
| -- | -- | -- |
| Fill | void | Fills elements of a rectangular array at the given position and size to a specific value. |
| GetRow | IEnumerable | Yields a row from a rectangular array. |
| GetColumn | IEnumerable | Yields a column from a rectangular or jagged array. |
| ToArrayString | string | Returns a simple string representation of an array. |

## Requirements (Windows 10 Device Family)

| [Device family](/windows/uwp/get-started/universal-application-platform-guide) | Universal, 10.0.16299.0 or higher |
| --- | --- |
| Namespace | Microsoft.Toolkit |
| NuGet package | [Microsoft.Toolkit](https://www.nuget.org/packages/Microsoft.Toolkit/) |

The Array Extensions supports .NET Standard

## API

* [ArrayExtensions source code](https://github.com/windows-toolkit/WindowsCommunityToolkit/blob/rel/7.1.0/Microsoft.Toolkit/Extensions/ArrayExtensions.cs)
31 changes: 31 additions & 0 deletions components/Extensions/samples/ClipToBoundsSample.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<Page x:Class="ExtensionsExperiment.Samples.ClipToBoundsSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ui="using:CommunityToolkit.WinUI"
mc:Ignorable="d">

<Grid Width="148"
Height="148"
ui:UIElementExtensions.ClipToBounds="{x:Bind IsClipped, Mode=OneWay}"
Background="{ThemeResource CardBackgroundFillColorDefaultBrush}"
BorderBrush="{ThemeResource CardStrokeColorDefaultBrush}"
BorderThickness="1">
<!-- We translate the inner rectangles outside of the bounds of the container. -->
<Rectangle Width="100"
Height="100"
Fill="{ThemeResource SystemFillColorAttentionBrush}">
<Rectangle.RenderTransform>
<TranslateTransform X="-50" Y="-50" />
</Rectangle.RenderTransform>
</Rectangle>
<Rectangle Width="100"
Height="100"
Fill="{ThemeResource SystemFillColorSuccessBrush}">
<Rectangle.RenderTransform>
<TranslateTransform X="50" Y="50" />
</Rectangle.RenderTransform>
</Rectangle>
</Grid>
</Page>
19 changes: 19 additions & 0 deletions components/Extensions/samples/ClipToBoundsSample.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// 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.

namespace ExtensionsExperiment.Samples;

/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
[ToolkitSampleBoolOption("IsClipped", true, Title = "Clip to Bounds")]
[ToolkitSample(id: nameof(ClipToBoundsSample), "ClipToBounds", description: "An extension for turning on clipping to the bounds of a container.")]

public sealed partial class ClipToBoundsSample : Page
{
public ClipToBoundsSample()
{
this.InitializeComponent();
}
}
31 changes: 31 additions & 0 deletions components/Extensions/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>
73 changes: 73 additions & 0 deletions components/Extensions/samples/DependencyObjectExtensions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
---
title: DependencyObjectExtensions
author: Sergio0694
description: The DependencyObjectExtensions type provides a collection of extensions methods for DependencyObject objects to aid in using the VisualTreeHelper class.
keywords: windows 10, uwp, windows community toolkit, uwp community toolkit, uwp toolkit, Visual Tree, extensions
dev_langs:
- csharp
- vb
category: Extensions
subcategory: Layout
discussion-id: 0
issue-id: 0
---

# DependencyObjectExtensions

The [`DependencyObjectExtensions`](/dotnet/api/microsoft.toolkit.uwp.ui.DependencyObjectExtensions) type provides a collection of extensions methods for [`DependencyObject`](/uwp/api/windows.ui.xaml.dependencyobject) objects. This class exposes several APIs to aid in using the [`VisualTreeHelper`](/uwp/api/Windows.UI.Xaml.Media.VisualTreeHelper) class. There are a number of reasons why walking the visual tree might be useful, which are mentioned [in the docs](/uwp/api/windows.ui.xaml.media.visualtreehelper?#traversing-a-visual-tree).

> **Platform APIs:** [`DependencyObjectExtensions`](/dotnet/api/microsoft.toolkit.uwp.ui.DependencyObjectExtensions)

## Syntax

```csharp
// Include the namespace to access extensions
using Microsoft.Toolkit.Uwp.UI;

// Find a visual descendant control using its name
var control = uiElement.FindDescendant("MyTextBox");

// Find the first visual descendant control of a specified type
control = uiElement.FindDescendant<ListView>();

// Find all visual descendant controls of the specified type.
// We use LINQ here to filter children of a specific type.
using System.Linq;

foreach (var child in uiElement.FindDescendants().OfType<ListViewItem>())
{
// ...
}

// Find the first visual ascendant control using its name
control = uiElement.FindAscendant("MyScrollViewer");

// Find the first visual ascendant control of a specified type
control = uiElement.FindAscendant<ScrollViewer>();
```

```vb
' Include the namespace to access extensions
Imports Microsoft.Toolkit.Uwp.UI.Extensions

' Find a visual descendant control using its name
Dim control = uiElement.FindDescendant("MyTextBox")

' Find the first visual descendant control of a specified type
control = uiElement.FindDescendant(Of ListView)()

' Find all visual descendant controls of the specified type
For Each child In uiElement.FindDescendants().OfType(Of ListViewItem)()
' ...
Next

' Find the first visual ascendant control using its name
control = uiElement.FindAscendant("MyScrollViewer")

' Find the first visual ascendant control of a specified type
control = uiElement.FindAscendant(Of ScrollViewer)()
```

## Examples

You can find more examples in the [unit tests](https://github.com/windows-toolkit/WindowsCommunityToolkit/tree/rel/7.1.0/UnitTests).
85 changes: 85 additions & 0 deletions components/Extensions/samples/DispatcherQueueExtensions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
---
title: DispatcherQueueExtensions
author: Sergio0694
description: Helpers for executing code on a specific UI thread through a DispatcherQueue instance.
keywords: windows 10, uwp, windows community toolkit, uwp community toolkit, uwp toolkit, extensions, winui3, xaml islands, dispatcher, dispatcherqueue, DispatcherHelper, DispatcherQueueExtensions
dev_langs:
- csharp
category: Extensions
subcategory: None
discussion-id: 0
issue-id: 0
---

# DispatcherQueueExtensions

The [`DispatcherQueueExtensions`](/dotnet/api/microsoft.toolkit.uwp.DispatcherQueueExtensions) type provides a collection of extensions methods for [`DispatcherQueue`](/uwp/api/windows.system.dispatcherqueue) objects that makes it easier to execute code on a specific UI thread. A `DispatcherQueue` instance can be retrieved and cached for later use, and then used through any of the available helper methods to dispatch a delegate invocation on it.

> **Platform APIs:** [`DispatcherQueueExtensions`](/dotnet/api/microsoft.toolkit.uwp.DispatcherQueueExtensions)

## Syntax

The `DispatcherQueueExtensions` type exposes a number of overloads of its `EnqueueAsync` method to dispatch either synchronous or asynchronous delegates, and to optionally have them return a value that is then relayed back to the caller through an awaitable task. Here are some examples of how these extension methods can be used:

```csharp
// Get a DispatcherQueue instance for later use. This has to be called on the UI thread,
// but it can then be cached for later use and accessed from a background thread as well.
DispatcherQueue dispatcherQueue = DispatcherQueue.GetForCurrentThread();

// Execute some code on the target dispatcher queue
await dispatcherQueue.EnqueueAsync(() =>
{
});

// Execute some code that also returns a value
int someValue = await dispatcherQueue.EnqueueAsync(() =>
{
return 42;
});

// Execute some asynchronous code
await dispatcherQueue.EnqueueAsync(async () =>
{
await Task.Delay(100);
});

// Execute some asynchronous code that also returns a value
int someOtherValue = await dispatcherQueue.EnqueueAsync(async () =>
{
await Task.Delay(100);

return 42;
});
```

## Migrating from [`DispatcherHelper`](..\helpers\DispatcherHelper.md)

The [`CoreDispatcher`](/uwp/api/windows.ui.core.coredispatcher) is being deprecated (and it will no longer work with XAML Islands or WinUI 3) and should no longer be used, as it had a number of limitations. Specifically, it relied on the assumption that each window had its own UI thread tied to it, which is not always the case. The new `DispatcherQueue` instead can be used going forwards, and it requires some changes in code that was previously relying on `CoreDispatcher` and `DispatcherHelper`. Specifically, a background thread can no longer retrieve the `CoreDispatcher` by just accessing the dispatcher associated to the "main window" for the application, because this concept does not apply anymore. Instead, a `DispatcherQueue` instance needs to be retrieved on the UI thread and cached for later use in a background thread.

If you were using `DispatcherHelper` on the UI thread, apply the following change (here we're using `Task.Run` to simulate some work being done in a background thread and accessing some UI component, and we're assuming for this example that there is a `TextBlock` control in our page called "MyTextBlock"):

```csharp
// Before
Task.Run(() =>
{
await DispatcherHelper.ExecuteOnUIThreadAsync(() =>
{
MyTextBlock.Text = "Hello from a background thread!";
});
});

// After
DispatcherQueue dispatcherQueue = DispatcherQueue.GetForCurrentThread();

Task.Run(() =>
{
await dispatcherQueue.EnqueueAsync(() =>
{
MyTextBlock.Text = "Hello from a background thread!";
});
});
```

## Examples

You can find more examples in the [unit tests](https://github.com/windows-toolkit/WindowsCommunityToolkit/blob/rel/7.1.0/UnitTests/UnitTests.UWP/Extensions/Test_DispatcherQueueExtensions.cs).
60 changes: 60 additions & 0 deletions components/Extensions/samples/EnumValuesExtension.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
---
title: EnumValuesExtensions
author: Sergio0694
description: A markup extension that returns a collection of values of a specific enum type.
keywords: windows 10, uwp, uwp community toolkit, uwp toolkit, markup extension, XAML, markup, enum
dev_langs:
- csharp
category: Extensions
subcategory: Markup
discussion-id: 0
issue-id: 0
---

# EnumValuesExtensions

The [`EnumValuesExtensions`](/dotnet/api/microsoft.toolkit.uwp.ui.EnumValuesExtensions) type implements a markup extension that returns a collection of values of a specific enum type. It can be useful to easily bind a collection of all possible values from a given enum type to a UI element such as a [`ComboBox`](/windows/uwp/design/controls-and-patterns/combo-box) or some other items container or selector control.

> **Platform APIs:** [`EnumValuesExtensions`](/dotnet/api/microsoft.toolkit.uwp.ui.EnumValuesExtensions)

## Syntax

Assuming we had an `Animal` enum type and we wanted the user to pick one of the available names, here is the XAML syntax that allows us to create a `ComboBox` and display all `Animal` values, directly from XAML and with no code-behind:

```xaml
<ComboBox
xmlns:ui="using:Microsoft.Toolkit.Uwp.UI"
xmlns:enums="using:MyApplication.Enums"
ItemsSource="{ui:EnumValues Type=enums:Animal}"
SelectedIndex="0"/>
```

In this example we're just relying on the default `ComboBox` item template, that will display the name of each `Animal` value in a [`TextBlock`](/uwp/api/windows.ui.xaml.controls.textblock) control. We could of course also define a custom item template if we wanted to show additional info for each individual `Animal` value, or if we wanted to further customize how each value is presented to the user.

## Examples

Binding to an enum property can be accomplished like so:

```xaml
<ComboBox
xmlns:ui="using:Microsoft.Toolkit.Uwp.UI"
xmlns:enums="using:MyApplication.Enums"
ItemsSource="{ui:EnumValues Type=enums:Animal}"
SelectedItem="{x:Bind SelectedAnimal, Mode=OneWay}" />
```

```csharp
private Animal selectedAnimal = Animal.Dog;

public Animal SelectedAnimal
{
get => selectedAnimal;
set
{
selectedAnimal = value;
OnPropertyChanged(nameof(SelectedAnimal));
}
}
```

You can find more examples in the [unit tests](https://github.com/windows-toolkit/WindowsCommunityToolkit/tree/rel/7.1.0/UnitTests).
Loading