Code Monkey home page Code Monkey logo

labs-windows's Introduction

๐Ÿงช Windows Community Toolkit Labs (Preview) ๐Ÿงช

Windows Community Toolkit Labs header

Welcome to the home of Windows Community Toolkit Labs. A place for all new components to be developed in 'experiments' for the Windows Community Toolkit (built on top of WinUI 2, WinUI 3, and Uno Platform)! Find out more about Toolkit Labs in our blog post here. It includes more about our motivations for having this space as well as how to setup the NuGet feed required to easily use experiments found in this repo.

This is the starting place for all new features to make it into the Windows Community Toolkit. It is a useful prototyping space as well as a space to work collaboratively on polishing a feature. This allows a final PR into the main Toolkit repo to go as smoothly as possible once a feature is ready to go.

Getting Started

See the list of our current open experiments to try here!

You can find the corresponding CommunityToolkit.Labs packages in our Azure DevOps Feed, find out more about Preview Packages here.

https://pkgs.dev.azure.com/dotnet/CommunityToolkit/_packaging/CommunityToolkit-Labs/nuget/v3/index.json

If you find an experiment useful, please up-vote ๐Ÿ‘ its corresponding issue and comment with any feedback. Each experiment has an issue assigned to it with the experiment label for tracking. Please file any feedback or issues about that experiment on that singular issue. For any other questions or concerns, please open a Discussion.

Otherwise, you can clone the repo, open the components directory, navigate within the folder for a particular experiment and open up it's solution file in Visual Studio. Run one of the project heads (ExperimentName.Uwp/Wasm/WinAppSDK) to see its samples.

Clone the repository

The tooling is in a submodule, so you'll need to use --recurse-submodules when cloning or pulling for the first time:

git clone --recurse-submodules https://github.com/CommunityToolkit/Labs-Windows.git

Build Requirements

  • Visual Studio 2022 (UWP & Desktop Workloads for .NET)
  • .NET 6 SDK
  • Windows App SDK
  • Windows SDK 19041
  • Run dotnet tool restore from the project root to install SlnGen
  • Run build scripts from the Developer Command Prompt for Visual Studio or from elsewhere after adding MSBuild.exe to your PATH

Adding a new Experiment

Note: In Preview we're currently not accepting new experiments beyond our trial list to ensure our infrastructure is stabilized, if you'd like to contribute please see where you can lend a hand with Labs itself here If you have an idea for a component though, please feel free to open a discussion here.

To start a new experiment, open up a new Discussion to propose your idea with the community. Be sure to follow the template and highlight reasons why and how your idea can aid other developers.

Once there is traction and your idea is approved, an issue will be created to track your experiment and its progress.

Then you can fork the Labs repo, create a new branch, and start working on your feature (or porting over your existing prototype).

dotnet new --install .\tooling\ProjectTemplate\

cd components

dotnet new ctk-component -n MyExperimentNameHere

Read more about creating a new experiment from the template folder here.

Then open a PR, not everything needs to be done in your initial PR, but some basically functionality and a usage example should exist. The Labs space is a great place to work on something over time, get feedback from the community, and collaborate with others. However, your initial PR should compile and have enough content for folks to understand how to leverage your component.

Modifying an Experiment

First fork the repo and create a new branch specific to your modification.

To work on an experiment you can navigate to it's subdirectory and open its own solution file. This will let you work on the feature, samples, docs, or unit tests for that specific component only in isolation.

Then submit a PR back to the repo with your modifications. Whoever owns the experiment can then work with you to integrate your changes. A maintainer will merge a PR once sign-off from the experiment owner is received.

When is an Experiment done?

Not all experiments are successful, and that's ok! That's why we experiment! ๐Ÿ‘จโ€๐Ÿ”ฌ๐Ÿ”ฌ๐Ÿ‘ฉโ€๐Ÿ”ฌ

If there is enough interest in an experiment, it can be time to move it into the main Windows Community Toolkit repo. These experiments should have all the components required implemented like a sample, documentation, and unit tests.

Open up an issue on the main Toolkit repo using the Toolkit Labs Transfer Issue Template. (TODO: Link) Use that issue to discuss where in the Toolkit the new component should be placed and what release it should be shipped in. An initial review pass of the code will happen as well. Once the transfer issue is approved, open up a PR to copy over the experiment to its new home.

Building the Sample App

First ensure you've met the Build Requirements or the build scripts will fail.

Next you can build the main Sample App solution to see all the experiments currently available in this repository by running the GenerateAllSolution.bat script in the repo root.

Then just open the CommunityToolkit.AllComponents.sln solution in Visual Studio. You can run one of the project heads such as CommunityToolkit.App.WinAppSdk to run the sample app for that platform.

If you'd like to run a head beyond UWP, Wasm, or the WinAppSDK, you'll need to run the UseTargetFrameworks.ps1 script first in the tooling/MultiTarget directory. e.g. .\UseTargetFrameworks.ps1 -targets all

If you'd like to test on Uno + Windows App SDK over Uno + UWP, run the UseUnoWinUI.ps1 script. e.g. .\UseUnoWinUI.ps1 -targets 3

If there's a specific experiment you're interested in instead, you can navigate to its directory and open up it's individual solution to see samples specific to that feature. You can also read the next section to find out how to grab a pre-built NuGet package for each feature available here.

๐Ÿ“„ Code of Conduct

This project has adopted the code of conduct defined by the Contributor Covenant to clarify expected behavior in our community. For more information see the .NET Foundation Code of Conduct.

๐Ÿข .NET Foundation

This project is supported by the .NET Foundation.

๐Ÿ† Contributors

Toolkit Contributors

Made with contrib.rocks.

labs-windows's People

Contributors

arlodotexe avatar avid29 avatar citelao avatar csmartdalton avatar hhchaos avatar jay-o-way avatar jeromelaban avatar kmgallahan avatar lalithanadimpalli avatar martinzikmund avatar michael-hawker avatar mrlacey avatar nerocui avatar niels9001 avatar sergio0694 avatar vgromfeld avatar wherewhere avatar yourordinarycat avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

labs-windows's Issues

Setup CI Infrastructure

Pooling from various discussions, there's a bit of stuff we want to have running in the CI so all experiments are automatically validated from tests provided by the developers. We should also include our template to ensure all new experiences should be functional out-of-the-box (and to validate CI/pipeline with a known component).

Document how Labs and WCT Processes work

Overview

This is a tracking/discussion issue around how Toolkit Labs works as part of the ecosystem of the Toolkit.

Basically, this is the lifecycle of a feature going from idea/concept to implementation and into the main Toolkit repository.

Proposed Process

This is my current thinking around how Labs and the Windows Community Toolkit repo work together to allow us better collaboration with our community as well as the ability for us to better manage our releases, features, and structure of maintaining a large project used by so many others.

Every New Feature Starts in Toolkit Labs ๐Ÿงช

  1. Someone (community member, toolkit maintainer, partner, etc...) [aka the experiment 'Champion'] has an idea for something they want to contribute to the Toolkit (or maybe even a prototype already).
  2. They should first post a Discussion in a new Thread under ๐Ÿ’ก Ideas forum
  3. There we can discuss the proposal and if the idea has merit for something we could see a number of folks using the Toolkit.
  4. If the proposal is acceptable, an Issue should get created (linked to the discussion). Issues will only track current experiments and have a checklist of criteria which experiments need in order to be considered to be migrated into the main Toolkit repo. E.g. Samples, Docs, Unit Tests, etc...
  5. A PR can be opened with an initial experiment (linking to the issue), at minimum it should contain functional code with some demonstration of the code working. It doesn't need to be complete or polished, it can be just a rough-prototype, but should show something that could be 'usable'. It doesn't need full docs or unit tests or anything at this point. Criteria for success and merging is basically that the PR has followed the process above, it builds and does something, and doesn't contain any malicious code (as we would expect).
  6. From here, folks can collaborate with the Toolkit team or others in the community to work on improving the feature, getting feedback from others via the NuGet Labs Preview Feed, etc... and work towards checking off the checklist of requirements. Folks can use the open issue to vote on the idea and provide comments or bugs as feedback (or the linked discussion). Votes on the issue will be the main ones tracked for popularity/prioritization of any Toolkit-team assistance.
  7. Once the checklist is nearing completion (and also earlier when the initial code is felt to be 'feature complete') a request can be made to do a more thorough review with the Toolkit team. This can point out more architectural concerns or issues we see in the API surface which could be improved upon to help with the generalization or applicability of the component in certain use-cases or to align with existing API conventions, for instance.
  8. Once the review has completed and sees no major red-flags, an issue is opened in the main Toolkit repo pointing back to the Experiment. The contributor may still have things to address at this point before final review, but the process to integrate into the main Toolkit will be green-lit at this point.

The other alternative is that an Experiment may not be successful (for whatever reason: technical hurdle, too niche, no interest from community, experiment champion abandons, etc...) and archived/closed.

The Main Toolkit Repo ๐Ÿงฐ

The Main Toolkit repo is reserved for tracking releases and work for the upcoming milestone. There are two main areas for feedback used in the Toolkit Repo:

  • Discussions will be used for Q&A and announcements/engagements with the community for planning, etc...
  • Issues will track bugs or other pieces of concreate/well-defined work that is tracked for the current release (or backlog). They will also be used to track features coming from Labs.

No issues will represent feature requests, those would go into the Toolkit Labs Discussions instead.

PRs that are outside the scope of maintenance and bug-fixes will be closed without a corresponding issue (unless small typo/trivial fixes).

Experiment Migration Process

  1. When an Issue is filed in the main repo coming from an approved experiment (w/ link), it is evaluated by the Toolkit team to identify where the feature fits within the current release cycle and can schedule an appropriate integration timeline. Where in the Toolkit (i.e. what package) that feature belongs in will be discussed as well.
  2. When given the go ahead, the experiment champion can open a PR on the main repo (linked to the issue in the main repo) migrating their code from the Labs repo into the appropriate place in the Toolkit. Ideally, since we have aligned infrastructure, we should have a script that can help with this part or something.
  3. They can then ensure it builds and get information about any other quality gates related to the full CI pipeline, for instance package size.
  4. At this point the Champion should have addressed any issues from the thorough review done in Labs.
  5. A Final Review is performed as part of the regular PR process (which should be streamlined by earlier reviews). The PR is then merged and the feature will ship in the next version of the Toolkit! ๐ŸŽ‰๐ŸŽ‰๐ŸŽ‰

Open Questions

  • When is something a new 'feature' vs. an improvement to an existing API and how do those fit in this process? Where do those get discussed if coming from the community?

Simplify Local Build Requirements

Dependent on #45? As mentioned in #44

Problem Statemnet

As we've been testing trying to build on top of Uno, there's a lot of extra build requirements to do so. We don't want to add this extra complexity for folks who want to get started with Labs and build something on Windows to get started. Part of the point of Labs is to make things simpler (even if we have a larger scope).

@Arlodotexe and I had a good brainstorm this afternoon based on feedback from @mrlacey around how we could address this.

Proposed Solution

What this issue tracks would be implementing a system that helps us build minimal platforms for UWP, WinAppSDK, and WASM as our core priorities for local development and codespaces, but then run a full build in the CI for validation and testing against other platforms and for packages in the feeds.

Technical Implementation

  1. The props file which contains all the TFMs would not be referenced directly by the projects in the repository. Instead, they'd refence a Local props file.
  2. The Local props file would be added to the .gitignore list so that it doesn't get checked-in and is cleaned with the repo when needed.
  3. We'd create a PowerShell Script which can copy the main props file and adjust the TFMS to either copy it in-full or in-part based on a command-line argument
  4. We'd add a Pre-Build step to the Head props file which can execute the PowerShell script to adjust the props file based on if a core-platform head is being requested to be built or another platform is.
  5. The CI would either run the script ahead of time, or more likely pass in the flag to ensure all platforms are built. We may even want to use this to do two different jobs to get early validation on core platforms vs. waiting to build for all platforms depending on the timing of those processes.

Better syntax for generated multiple choice attributes

Background / Problem

In #29, we added generated sample options to the sample system. This included a multiple choice option, where due to the limitations of attributes, the syntax for a single multi-choice option looks something like:

    [ToolkitSampleMultiChoiceOption("TextForeground", label: "Teal", value: "#0ddc8c", title: "Text foreground")]
    [ToolkitSampleMultiChoiceOption("TextForeground", label: "Sand", value: "#e7a676")]
    [ToolkitSampleMultiChoiceOption("TextForeground", label: "Dull green", value: "#5d7577")]

There's a lot of room for improvement here. @michael-hawker and I had a brief discussion in the UWPCommunity Discord (starting here, ending here) on ways that we can improve on it.

Solution

Since attributes lack the ability to hold any data structure that resembles a key-value pair, and since Source generators allow us to do custom validation of data given to attributes, we eventually landed on the following syntax:

 [ToolkitSampleMultiChoiceOption(propname: "TextForeground", title: "Text foreground", "Teal : #0ddc8c", "Sand : #e7a676", "Dull green : #5d7577")]

// With different formatting.
 [ToolkitSampleMultiChoiceOption(propname: "TextForeground", title: "Text foreground", 
     "Teal       : #0ddc8c", 
     "Sand       : #e7a676",
     "Dull green : #5d7577")]
     
// With different formatting.
 [ToolkitSampleMultiChoiceOption("TextForeground", title: "Text foreground",
        choices: new string[] { "Teal : #0ddc8c",    "Sand : #e7a676",    "Dull green : #5d7577" })]

The goal was to replace the function of a ValueTuple without making things overly complicated, while still closely pairing the label to the value (e.g. not using 2 separate string[]).

We landed on using :, a colon surrounded by a space on both sides, as a separator for a key-value pair.

We'll need to

  • Refactor the source generators to use this
  • Refactor the existing samples to use this
  • Gut any custom diagnostic generators and unit tests for the old syntax
  • Add new diagnostic generators to ensure each string is properly formatted.
  • Trim whitespace from the end of each label, and from the start of each value (allows for custom alignment)
  • Add an optional flag to disable whitespace trimming, so values that require leading whitespace can be used if needed. The use cases here are very few at first glance, but not nonexistent. Should be an easy add.

Multiple samples for the same Lab/Experiment

Overview:

As mentioned here, we may want to take inspiration from the XAML Control Gallery and allow for multiple, separate samples under the same Lab/Experiment.

This would help clean up samples that already contain multiple other samples, like SwitchPresenter, OrbitView, and TextBoxMask, by physically separating them into separate samples with their own copy-able code and settings to tweak.

It would also allow us to embed each one inline with documentation, or deep-link to a very specific sample.

Current toolkit:

image
image

XAML Control Gallery (proposed approach)

image

image

Enforce code styling and editor config

The Labs repo is using default settings for code styling and .editorconfig. We need to bring in the .editorconfig and other code styling analyzers from the main repo.

NuGet packages are including Labs-Only Source Generators

The NuGet packages we're outputting are including our Labs-only source generators:

image

This makes them unusable/consumable by others.

This is because they're being included in the Labs.MultiTarget.props file used by the library projects:

<!-- Source generator props -->
<ItemGroup>
<ProjectReference Include="$(RepositoryDirectory)\common\CommunityToolkit.Labs.Core.SourceGenerators.XamlNamedPropertyRelay\CommunityToolkit.Labs.Core.SourceGenerators.XamlNamedPropertyRelay.csproj"
OutputItemType="Analyzer" ReferenceOutputAssembly="True" />
<ProjectReference Include="$(RepositoryDirectory)\common\CommunityToolkit.Labs.Core.SourceGenerators\CommunityToolkit.Labs.Core.SourceGenerators.csproj"
OutputItemType="Analyzer" ReferenceOutputAssembly="True" />
</ItemGroup>

My current work is in this branch:
https://github.com/CommunityToolkit/Labs-Windows/tree/feature/sg-head-only

It wasn't working properly, but I may have fixed it...

Investigate non-reflection alternatives to current sample system

Overview

The current sample system works like this:

  1. Sample pages are decorated with a ToolkitSampleAttribute containing metadata about the sample.
  2. A reference to a sample project is added to an app head.
  3. When the app is loading, it iterates through all loaded assemblies.
  4. When it comes across an assembly with "sample" in the name, it searches for Pages, then for the ToolkitSampleAttribute.
  5. If the data is found, it pulls the page in and makes it available for viewing.

The problem

The highly dynamic nature of this approach also brings a potential problem: tree shaking. Any system that trims out unused code paths, such as .NET Native or the IL Linker used in WebAssembly, will trim out entire sample projects due to being unreferenced.

This may not be an immediate problem, but I've made systems like this before and it always becomes a problem, especially when dealing with multiple of them like we will be. Since we need to have this nailed down for the templates, preemptively solving this may be a good idea.

The solution

Get rid of reflection entirely. Alternatives have been briefly discussed before. (see source generators and registry system), both of which can be templated pretty easily.

Source generators have the advantage of not changing our API or templates if we implement post-release, but will take much longer to implement, so we should investigate that last.

Keep in mind that no matter what solution we go with (including keeping the current one), the template system will need additional scripting to add project references to the multi-sample app, so we'll have that tool at our disposal.

Other ideas are encouraged! ๐Ÿ‘‡

Correlate Sample Pages

  • Share Image Assets
  • Custom 'injected'/shared App.xaml.cs
  • Simple Shell page
    • List sample pages
    • Navigate to Sample

Can't build WASM and Individual Project Solutions

Was trying to test things all-up for latest rename PR. Couldn't get the WASM and Individual project solutions to build, looks like they're missing references to the source generator projects? Not sure if that's expected. Everything seems to work fine on the Toolkit.Labs.All.sln

3>H:\code\Labs-Windows\CommunityToolkit.Labs.Wasm\CommunityToolkit.Labs.Wasm.csproj : error NU1105: Unable to find project information for 'H:\code\Labs-Windows\Common\CommunityToolkit.Labs.Core.SourceGenerators\CommunityToolkit.Labs.Core.SourceGenerators.csproj'. If you are using Visual Studio, this may be because the project is unloaded or not part of the current solution so run a restore from the command-line. Otherwise, the project file may be invalid or missing targets required for restore.
3>H:\code\Labs-Windows\CommunityToolkit.Labs.Wasm\CommunityToolkit.Labs.Wasm.csproj : error NU1105: Unable to find project information for 'H:\code\Labs-Windows\Common\CommunityToolkit.Labs.Core.SourceGenerators.XamlNamedPropertyRelay\CommunityToolkit.Labs.Core.SourceGenerators.XamlNamedPropertyRelay.csproj'. If you are using Visual Studio, this may be because the project is unloaded or not part of the current solution so run a restore from the command-line. Otherwise, the project file may be invalid or missing targets required for restore.

FYI @Arlodotexe, do we just need to add the other projects for the core source generators here?

Codespace: Build dropdown broken after adding platform heads

When we added the rest of the cross-platform heads, we also moved the existing projects into a new "Platforms" folder to keep things tidy.

This wasn't tested in a Codespace, where the path to the WASM head is hardcoded, resulting in this error when selecting "All Samples" from the dropdown:

image

Multi-sample view

We need a page that displays all available samples and lets the user browser and navigate between them.

Samples from the same project should be displayed under the same page.

The end goal is something similar to the XAML Controls Gallery:

image

Full support for Uno Platform

Background

To keep things as easy as possible for our users, we want the Labs (and eventually, the Toolkit) to support:

  • UWP - WinUI 1/2 (Windows)
  • WinAppSDK - WinUI 3 (Windows)
  • Uno Platform (all other platforms)

The problem

We're already multi-targeting between these 3 things. However, "Uno" isn't a standalone target framework, but rather a polyfill for WinUI and WinRT on many possible other platforms.

We're currently supporting Uno exclusively on WinUI 2 under WASM. This means any WinUI 2 projects using the toolkit won't need separate packages for Uno under their WASM head.

However, using Uno on WASM under WinUI 3 is not supported, as well as WinUI 2 on Android, WPF, iOS, MacOS, etc.

The solution

We need to investigate and add support for

  • Multitargeting remaining Uno target frameworks, even if we don't use them for samples (though maybe we want sample projects for these, for testing?)
  • Uno under both WinUI 2 and WinUI 3. This may involve conditionally including packages based on a flag other than the Framework version.

[Feature]Make AttachedCardShadow available for 1809 update

Describe the problem this feature would solve

Hi @Ryken100, sorry to bother you but I was searching in the issues and pull requests and I didn't found pull request for updating AttachedCardShadow to accomplish 1809 update, you told me that the reason of working of this type of shadow only on May 2019 update and above that it's depending on CompositionVisualSurface and there is way to make it working on October 2018 update and there is will be a future update to accomplish this

Describe the solution

Making AttachedCardShadow working on 1809 update

Describe alternatives you've considered

Additional context & Screenshots

Sample system: Remove usage of Activator.CreateInstance

Background

As part of #18, we moved from Reflection to Source Generators to avoid potential issues with IL Trimmers, tree shakers and .NET Native, as using reflection in combination with these usually cause problems.

Problem

When submitting the PR for this issue (#22), we missed a spot: Activator.CreateInstance is still used to instantiate the sample pages. This means that the sample pages have no reference in the compiled project when tree shaking is involved, and they get removed, making them unusable via Reflection.

Solution

The source generators for the sample system need to have a factory method that creates the sample control instance we need, and all uses of Activator.CreateInstance need to be removed.

[Feature] Behaviors for WeakReferenceMessenger and StrongReferenceMessenger

Problem

The MVVM Toolkit has a StrongReferenceMessenger and a WeakReferenceMessenger, used for relaying messages via the messenger pattern.

These APIs are extremely handy for passing messages around to decoupled parts of the app, but they require code-behind to send and receive messages.

In scenarios where the user may prefer or be forced to write only XAML (such as retemplating a control), it becomes cumbersome to send and receive messages with the default Messenger.

Solution

It would useful to developers if they had the ability to send and receive messages for WeakReferenceMessenger and StrongReferenceMessenger via Behavior actions and triggers in XAML.

tl;dr

XAML has Behaviors.
Behaviors are like bacon.
Messenger needs bacon.

Examples

Sending a message

The user specifies a SendMessageAction, changes the messenger to Weak or Strong as needed, and provides the model to send.

<ItemsControl x:Name="UsersList" ItemsSource="{x:Bind AvailableUsers}" SelectionMode="Single">
    <Interactivity:Interaction.Behaviors>
        <Interactions:EventTriggerBehavior EventName="SelectionChanged">
            <tk:SendMessageAction Messenger="Weak">
                 <tk:SendMessageAction.Message>
                     <messages:UserChangedMessage User="{Binding SelectedItem, ElementName=UsersList}" />
                 <tk:SendMessageAction.Message>
            </tk:SendMessageAction>
        </Interactions:EventTriggerBehavior>
    </Interactivity:Interaction.Behaviors>
</ItemsControl>

Receiving a message

Unconditional triggering

It would be easy to just invoke an action when a message of a certain type is emitted.

<UserControl x:Name="Container">
    <Interactivity:Interaction.Behaviors>
        <tk:ReceiveMessageTrigger Messenger="Weak" Type="messages:UserChangedMessage">            
            <Interactions:ChangePropertyAction TargetObject="{Binding ElementName=Container}" PropertyName="Visibility" Value="Collapsed"/>
        </tk:ReceiveMessageTrigger>
    </Interactivity:Interaction.Behaviors>
</UserControl>

Conditional triggering

However, unconditional triggering doesn't fit most user scenarios. We need the ability to conditionally execute the behavior based on data in the model, since the action performed often depends on what data is in the message.

There's a few options here. Which approach is best is open to discussion. (I'm personally a fan of the filters approach.)

Using filters declared in XAML

This is similar to DataTriggerBehavior, with a few key differences

  • A filter is always compared against received messages of the same type.
  • Multiple filters can be declared.
    • Multiple filters are treated as implicitly && (and).
    • Can be changed to || (or) by declaring Optional="True".
<UserControl x:Name="Container">
    <Interactivity:Interaction.Behaviors>
        <tk:ReceiveMessageTrigger Messenger="Weak" Type="messages:UserChangedMessage">
            <tk:ReceiveMessageTrigger.Filters>
                <tk:ReceivedMessageFilter Property="IsLoggedIn" ComparisonCondition="Equal" Value="False" Optional="True"  /> 
                <tk:ReceivedMessageFilter Property="CanLogIn" ComparisonCondition="Equal" Value="True"  /> 
            </tk:ReceiveMessageTrigger.Filters>
            <Interactions:ChangePropertyAction TargetObject="{Binding ElementName=Container}" PropertyName="Visibility" Value="Collapsed"/>
        </tk:ReceiveMessageTrigger>
    </Interactivity:Interaction.Behaviors>
</UserControl>

Using a converter

This option has the most flexibility but requires C# code and a questionable usage of converters.

public sealed class CustomUserChangedMessageFilterConverter : IValueConverter
{
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static bool Convert(UserChangedMessage value)
    {
        return !value.IsLoggedIn;
    }

    public object Convert(object value, Type targetType, object parameter, string language)
    {
        return value is UserChangedMessage message && Convert(message);
    }

    public object ConvertBack(object value, Type targetType, object parameter, string language)
    {
        throw new NotImplementedException();
    }
}
<UserControl x:Name="Container">
    <Interactivity:Interaction.Behaviors>
        <tk:ReceiveMessageTrigger Messenger="Weak" Type="messages:UserChangedMessage" MessageFilterConverter="{StaticResource CustomUserChangedMessageFilterConverter}">            
            <Interactions:ChangePropertyAction TargetObject="{Binding ElementName=Container}" PropertyName="Visibility" Value="Collapsed"/>
        </tk:ReceiveMessageTrigger>
    </Interactivity:Interaction.Behaviors>
</UserControl>

Additional info

Addressing one big potential concern ahead of time:

"But it's an anti-pattern!"

From what I've read, it's standard practice to use the Messenger pattern in ViewModels almost exclusively. You'd be hard pressed to find an example of the messenger pattern used outside of a ViewModel.

At some point it became the default way to use the Messenger pattern, and after using it in combination with pure trickle-down MVVM for a few years, I'm really not sure why.

"Who decided that anyway?"

In my ventures developing apps, I've found this statement to be flawed for a few reasons.

About 90% of the time, controls do not / should not exclusively use a ViewModel for internal implementation.
Instead, almost all well designed Controls use DependencyProperties to consume and bind data.

Controls may consume an existing "backend/data" ViewModel via DependencyProperty.
Controls can add more DependencyProperties, event handlers, and more for custom behavior.
If needed, the control can wrap a given "backend/data" VM with a control-specific ViewModel if the data structure doesn't quite meet its needs.

And so on.

What is it, then?

The messenger pattern itself closely resembles a pub-sub pattern, and so all decoupling benefits of the pub-sub pattern come with it, no matter the context, and even outside of ViewModels.

For example

The messenger pattern is fantastic for general app navigation. But if a well-crafted control, which uses DependencyProperties to consume and bind data, doesn't need a ViewModel, then how do you send a navigation message?

You do it in the Control code-behind. Or, with this new Behavior, you could do it directly in XAML.

Help us help you

Yes, I'd like to be assigned to work on this item.

Codespaces: Auto-set WebAssembly app port to public

Problem

As stated in #19, Uno requires port 5000 to be made public to view the app in a Codespace. After much research, I wasn't able to find a way to automatically make this port public.

Solution

GitHub Codespaces appear to be in active development, with public ports only being added around March 2021. Since Uno requires port 5000 to be public for their WebAssembly app to run in a Codespace, this should be done automatically for user convenience.

Enable nullables globally

Since Labs is a fresh start, we'd like to enable nullables globally in all current and future projects. We can do this by setting <Nullable>enable</Nullable> in Windows.Toolkit.Common.props and in the template for new projects.

[Build] Experiment detection for intermediate build

Setting up #65 and #33 gave me a thought.

I'll have to check the git commands again, though it is hard to get a list of changed files from the CI as the git history isn't pulled by default.

If we could, we could try and detect the modified experiments as part of a PR and have a separate job which uses that info to build/validate those experiments only (alongside the full build).

This could be useful as our all-up build grows to give quick status back on the immediate change. We could also use it to push these interim changes of packages to the PR specific feed to bring back that functionality we have in our main repo currently...

Thoughts?

Rename UWP namespaces to WinUI

Initial setup of the Labs repo brought existing conventions from the main toolkit, namely the usage of "UWP" in our namespaces.

Since Labs will be multi-targeting Uno, UWP, and the WinAppSDK moving forward, we need to rename "UWP" to "WinUI" in all namespaces (except, of course, the UWP project heads).

All-up Testing Goals/Priorities

Related to #3

Testing Goals

We want to make testing approachable and easy for our developers. We've learned from the main Windows Community Toolkit repo that we can get a lot of flexibility in testing our UI features with the Unit Test infrastructure and the VisualUITestBase helper. This has allowed us a lot of depth in exercising UI without much added complexity to a standard Unit Test.

Ideally, we can have a single test (as written) run across one or more target frameworks to help us validate our extra platform targets. UWP and the WinAppSDK are our main priorities, next coming WASM, and then another like Android would probably be the easiest.

UI Testing has been trickier. Our current setup is pretty complex and a bit fragile. It'd be interesting to learn if there are other options out there that may simplify this process.

Unit Tests (Majority of our tests)

  • P0: Write a Single Test
  • P0: Run with both UWP and WinAppSDK? without modification (can use a separate head if needed)
  • P1: To Investigate: Can we get 1+ Other Platforms (WASM, Android...) to work?

UI Tests (~5-15% expected of needs I believe)

  • P0: Write a Single Test
  • P0: Run with both UWP and WinAppSDK?
  • P3: Run against another platform...

Also

  • Integrate tests into the CI process
  • Have easily readable test results (& badges?)
  • Update test projects to use shared props

Summary

I think if we can at least get to a point where a single unit test, as written, runs across UWP, WinAppSDK, and at least one other platform, and a UI Test that runs on UWP and WinAppSDK. That should cover 95+% of our testing needs/requirements.

As long as adding tests is simple and easy to test locally (and in the CI for validation), then that should be the main thing. We want to lower the barrier to writing tests so we can write more tests to help us maintain code. This enables us or others to better manipulate existing code to fix issues without worry of breaking core functionality when the original code may not be theirs.

Correlating Unit Tests

Each feature should have their own unit test project, these should be easy to run within VS for the developer.

At the same time we want the CI/pipeline to run all the unit tests together and report any issues back.

Set up launch.json to open each sample in VSCode

In order to launch and debug in VSCode, the .vscode/Launch.json file needs to be set up for each sample with options to run the project.

The guidance from Uno is one approach, but will quickly bloat the Run dropdown and requires additional user interaction.

Instead, we can take a cue from the Uno QuickStart guide, and set up a small script that takes a project path as passed as an argument. This will allow us to have 1 project per dropdown item.

This script will need to:

  1. Run uno-check --non-interactive --target wasm --fix to set ensure the environment is set up properly, without bothering the user.
  2. Tell omnisharp to use the selected project (needs investigation)
  3. dotnet run the app at the given path and kick off the debug session.

Auto-Generate All Solution File

We should have a solution template but then auto-generate the required All-up solution to detect/inject the required experiment projects.

This should also let us toggle between running on Uno.UI vs. Uno.WinUI for the platform heads for when we want to test each set all-up, as discussed in #28.

This also simplifies how templating works.

We expect developers to be focused on individual experiment solutions, so not having an all-up solution lends itself to that, and we only need this to build or test the sample locally for more complex development activities.

We'll just have to run the script ahead of time to get it.

Single-sample solution not building in codespace

Problem

In #61, the single-sample solution for CanvasLayout was modified and organized to accommodate unit tests.

However, the src and samples folders were also renamed to Src and Samples. On Windows, paths are case insensitive, so this caused no issues, but paths are case sensitive on Linux. Since the launch.json file used by Codespaces wasn't updated to accommodate this, we're no longer able to build CanvasLayout in a codespace.

image

Solution

We need to either

  • Fix launch.json and make sure all paths in the repo are using the new paths.
  • Or, since these folder names can't be considered proper nouns like Labs and CanvasLayout can, revert the change and use lowercase.

Can we remove the option to run non-runnable projects?

The first four options in the run list can't be run:

image

I wonder if there's a way we can hide them in this list in Visual Studio or if that's not possible?

If anything, maybe we can file a feature request for a future VS version... ๐Ÿ˜‹

Just wanted to track this here for now.

Live-Share Enabled by Default

Arlo was suggesting it'd be cool if when opening a codespace by default it'd enable a live-share session/link so that it's super easy folks to collaborate (either in a codespace or with local vscode). (Would want it to point to correct branch/etc...)

Docs Correlation

What do we do for docs?

We should have a markdown file similar to that of what we use in the docs.microsoft.com template.

Should we have a 'feature' doc plus docs for each sample?

Can we correlate specific samples to specific pages?

Uno QuickStart Environment

Can we have a browser-based view something like https://github.com/unoplatform/Uno.QuickStart to make it easier to browse experiments?

Can we do something where we only show the UWP head in VS and then the WASM head if in the browser? How do we not overload a developer with multiple heads when trying to develop a feature? Is there an easier way to select which head to run?

Setup access to preview toolkit packages

Problem

Much like the current main toolkit repo, we'll want the ability to reference the most up-to-date version of the toolkit.

Solution

Add nuget configuration that lets us reference the most recent version. See here for an example.

[Feature] Node Graph Control

Describe the problem this feature would solve

A node graph is a fairly niche control, but as UWP becomes used for more technical projects flow charts are more common. This would be a useful control for creating a graphs visually.

Describe the solution

A control with Nodes, Ports, and Connections. Similar to Blender, Unity, or UE4 shaders.

Describe alternatives you've considered

Anytime someone wants this control, they would need to write it themselves.

Additional context & Screenshots

image

macOS and iOS builds are failing successfully in Visual Studio

When building in Visual Studio, all projects appear to build successfully.


image

However, on closer inspection, macOS and iOS are failing to build with the message:

"D:\a\Labs-Windows\Labs-Windows\Toolkit.Labs.All.sln" (default target) (1:2) ->
"D:\a\Labs-Windows\Labs-Windows\Platforms\CommunityToolkit.Labs.iOS\CommunityToolkit.Labs.iOS.csproj" (default target) (12:6) ->
(_UnoSourceGenerator target) -> 
  MSBUILD : error : Failed to read [D:\a\Labs-Windows\Labs-Windows\Common\CommunityToolkit.Labs.Core.SourceGenerators\bin\iPhoneSimulator\Release\netstandard2.0\CommunityToolkit.Labs.Core.SourceGenerators.dll], Could not find a part of the path 'D:\a\Labs-Windows\Labs-Windows\Common\CommunityToolkit.Labs.Core.SourceGenerators\bin\iPhoneSimulator\Release\netstandard2.0\CommunityToolkit.Labs.Core.SourceGenerators.dll'. [D:\a\Labs-Windows\Labs-Windows\Platforms\CommunityToolkit.Labs.iOS\CommunityToolkit.Labs.iOS.csproj]


"D:\a\Labs-Windows\Labs-Windows\Toolkit.Labs.All.sln" (default target) (1:2) ->
"D:\a\Labs-Windows\Labs-Windows\Platforms\CommunityToolkit.Labs.macOS\CommunityToolkit.Labs.macOS.csproj" (default target) (13:6) ->
  MSBUILD : error : Failed to read [D:\a\Labs-Windows\

(Copied from #43)

This seems to be caused by the build system trying to use iPhoneSimulator as the Platform for the source generator project, which is netstandard2.0 and does not support this.

[Feature] Marquee Text Control

Describe the problem

Looking for a convenient TextBlock that can scroll text like a Marquee

Describe the solution

A MarqueeText control that uses a Storyboard and two TextBlocks to scroll text across the screen if it doesn't fit

Alternatives

No response

Additional info

I wrote a control like this for StrixMusic, however I think I could do it better if I took another go at it

Help us help you

Yes, I'd like to be assigned to work on this item.

Add support for using .NET 6 with the WASDK 1.0 release

As per this request to create a tracking issue, and this comment:

Yeah WinUI 3/WASDK is still based on .NET 5 from their last release. So I'm not sure yet on the timing of a plan on migrating to .NET 6 yet, we just synced with their release for the last 1.0-preview3 finally. Once they support it though, we'll update our WinUI packages to match.

The CommunityToolkit.WinUI package needs to be updated to support .NET 6 as a target in order to use it with WASDK 1.0.

Project Release Date
.NET 6 Nov 8
WASDK 1.0 Nov 16
WCT v.next ?

Unify TargetFrameworks across all projects and libs

In the future, we'll have many, many sample projects, all using a hardcoded TargetFramework. If these ever get updated, it will be more difficult to update the TargetFramework for a specific platform when there are pending PRs.

To help make this easier, we should unify all TargetFramework values into a single props file which can be imported, allowing us to access the target framework for a specific head via a variable (such as $(WinAppSdkTargetFramework)) .

WASM / Skia sample heads show white screen under WinUI 3

In #75, we added the ability to switch to WinUI 3 for all Uno projects. While this works and all platforms compile both inside and outside of Visual Studio, there's a lingering issue where Skia-based heads (WPF, Gtk) and WebAssembly show a blank white screen upon loading the app.

Upon inspecting the Visual Tree using the DevTools in WASM, it appears that the Arrange pass was skipped entirely, leaving all UI elements loaded but not displayed.

Enable Grid to dynamically switch layouts

Discussed in https://github.com/CommunityToolkit/WindowsCommunityToolkit/discussions/4470

Originally posted by nandin-borjigin January 30, 2022

Usecase

Imagine we want to show a list of items and each list item is a 3-column grid.

+---+-------------+-------------------------------+
| 1 | Lorem Ipsum | Lorem ipsum dolor sit amet... |
+---+-------------+-------------------------------+

Now, we want to be responsive to the window size changes and decide to collapse this list item into 2 rows when the window width is narrow.

+-------+-----------------------+
|   1   |      Lorem Ipsum      |
+-------+-----------------------+
| Lorem ipsum dolor sit amet... |
+-------------------------------+

Potential approach

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="Auto"/>
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto"/>
        <ColumnDefinition Width="Auto" x:Name="SecondColumn"/>
        <ColumnDefinition Width="*" x:Name="ThirdColumn"/>
    </Grid.ColumnDefinitions>
    <VisualStateManager.VisualStateGroups>
        <VisualStateGroup>
            <VisualState x:Name="NarrowState">
                <VisualState.StateTriggers .../> <!-- Trigger implementation omitted -->
                <VisualState.Setters>
                    <Setter Target="Description.(Grid.Row)" Value="1"/>
                    <Setter Target="Description.(Grid.Column)" Value="0"/>
                    <Setter Target="Description.(Grid.ColumnSpan)" Value="2"/>
                    <Setter Target="ThridColumn.Width" Value="0"/>
                    <Setter Target="ThridColumn.Width" Value="*"/>
                </VisualState.Setters>
            </VisualState>
        </VisualStateGroup>
    </VisualStateManager.VisualStateGroups>
    <TextBlock x:Name="Number">1</TextBlock>
    <TextBlock x:Name="Title">Lorem Ipsum</TextBlock>
    <TextBlock x:Name="Description">Lorem ipsum dolor sit amet...</TextBlock>
</Grid>

Problem

It's not really intuitive to declare a 2 x 3 grid layout when what we really need is either 1 x 3 or 2 x 2, depending on the window width. In above approach, we're imperatively dictating how the narrow layout would be instead of declaratively describing it and let the library handles the dirty work.
Further, another problem here is the visual state setter would quickly become maintenance hell when the layout becomes slightly complex. Just imagine what if we want to add column spacing to the grid.

Normal
+---+:+-------------+:+-------------------------------+
| 1 |:| Lorem Ipsum |:| Lorem ipsum dolor sit amet... |
+---+:+-------------+:+-------------------------------+

Narrow
+-----+:+-----------------------+:+
|  1  |:|     Lorem Ipsum       |:|
+-----+:+-----------------------+:+
| Lorem ipsum dolor sit amet... |:|
+-------------------------------+:+

This is what we would get if we simply add ColumnSpacing="10" on the Grid element. The gutter between 2nd and 3rd column is still there since the 3rd column is effectively there even if it's of 0 width, so the spacing exists. To better workaround this, we need to modify the visual state setters. We need to make the Title element span 2nd and 3rd columns and make the Description element span 3 columns. And this is only for a minor change like adding a column spacing.

Proposal

Provide Grid with a set of attached properties to enable programmers to declaratively describe the possible layouts and easily switch between them.

<Grid x:Name="RootGrid" GirdExentions.ActiveLayout="Normal">
    <!-- Declaratively define the possible layouts. -->
    <!-- GridExtensions.Layouts is a dictionary of GridLayoutDefinition -->
    <GridExtensions.Layouts>
        <GridLayoutDefinition x:Key="Normal">
            <!-- A GridLayoutDefinition consists of -->
            <!-- row definitions, column definitions and an area definition -->
            <GridLayoutDefinition.RowDefinitions>
                <RowDefinition Height="Auto"/>
            </GridLayoutDefinition.RowDefinitions>
            <GridLayoutDefinition.ColumnDefinitions>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition Width="*"/>
            </GridLayoutDefinition.ColumnDefinitions>
            <!-- Area definition just simply puts down -->
            <!-- children names in desired order -->
            Number Title Description
        </GridLayoutDefinition>
        <GridLayoutDefinition x:Key="Narrow">
            <GridLayoutDefinition.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="Auto"/>
            </GridLayoutDefinition.RowDefinitions>
            <GridLayoutDefinition.ColumnDefinitions>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition Width="*"/>
            </GridLayoutDefinition.ColumnDefinitions>
            Number      Title; <!-- semicolon is used to separate differnt rows -->
            Description Description <!-- row/column span is expressed by repeating the elment name -->
        </GridLayoutDefinition>
    </GridExtensionstensions.Layouts>
    <VisualStateManager.VisualStateGroups>
        <VisualStateGroup>
            <VisualState x:Name="NarrowState">
                <VisualState.StateTriggers .../> <!-- Trigger implementation omitted -->
                <VisualState.Setters>
                    <!-- Only ActiveLayout property on the root grid needs to change according to the visual state -->
                    <Setter Target="RootGrid.(GridExtensions.ActiveLayout)" Value="Narrow">
                </VisualState.Setters>
            </VisualState>
        </VisualStateGroup>
    </VisualStateManager.VisualStateGroups>
    <TextBlock x:Name="Number">1</TextBlock>
    <TextBlock x:Name="Title">Lorem Ipsum</TextBlock>
    <TextBlock x:Name="Description">Lorem ipsum dolor sit amet...</TextBlock>
</Grid>
```</div>

[Feature] AnimatedCornerRadius

Describe the problem this feature would solve

I have made a TemplatedControl that have 4 new properties (TopLeftCorner, TopRightCorner, BottomLeftCorner, BottomRightCorner) and each of them control in the radius of corner that associated with.
And the purpose of doing this that in WPF there type of animation called: "ThicknessAnimation" and this animation provide me the ability to animate the properties that are from thickness class like: (margin, padding, borderThickness ...) and because this animation isn't available in UWP the solutions simply was making a dependency property for each paramerter of the thickness and animate them all such as: (make four properties for the Margin => LeftMargin, TopMargin, RightMargin, BelowMawrgin, and animate all of them or some of them depending on your needs in one storyboard) and in my sample here I made animation for the corners of border

The generic xaml for this TemplatedControl :

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:CalculatorControlSample"
    xmlns:local2="using:CalculatorControlSample.Temp">

    <Style TargetType="local2:AnimatedCornerRadius">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="local2:AnimatedCornerRadius">
                    <Grid>
                        <Border
                        Width="{TemplateBinding Width}"
                        Height="{TemplateBinding Height}"
                        Opacity="{TemplateBinding Opacity}"
                        Background="{TemplateBinding Background}"
                        BorderBrush="{TemplateBinding BorderBrush}"
                        BorderThickness="{TemplateBinding BorderThickness}"
                        CornerRadius="{TemplateBinding CornerRadius}"
                        HorizontalAlignment="{TemplateBinding HorizontalAlignment}"
                        VerticalAlignment="{TemplateBinding VerticalAlignment}"/>

                        <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                          VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                                          Margin="{TemplateBinding Padding}"
                                          Content="{TemplateBinding Content}"/>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>

And .cs file

public sealed class AnimatedCornerRadius : Control
 {
        public AnimatedCornerRadius()
        {
            this.DefaultStyleKey = typeof(AnimatedCornerRadius);
        }

        public object Content
        {
            get { return (object)GetValue(ContentProperty); }
            set { SetValue(ContentProperty, value); }
        }
        public static readonly DependencyProperty ContentProperty =
            DependencyProperty.Register(nameof(Content), typeof(object),typeof(AnimatedCornerRadius), new PropertyMetadata(null));

        public int TopLeftCorner
        {
            get { return (int)GetValue(TopLeftCornerProperty); }
            set { SetValue(TopLeftCornerProperty, value); }
        }
        public static readonly DependencyProperty TopLeftCornerProperty =
            DependencyProperty.Register(nameof(TopLeftCorner), typeof(int), typeof(AnimatedCornerRadius),
                new PropertyMetadata(0, (s, e) =>
                {
                    ((AnimatedCornerRadius)s).CornerRadius = new CornerRadius(
                        double.Parse(e.NewValue.ToString()),
                        ((AnimatedCornerRadius)s).CornerRadius.TopRight,
                        ((AnimatedCornerRadius)s).CornerRadius.BottomRight,
                        ((AnimatedCornerRadius)s).CornerRadius.BottomLeft);
                }));

        public int TopRightCorner
        {
            get { return (int)GetValue(TopRightCornerProperty); }
            set { SetValue(TopRightCornerProperty, value); }
        }
        public static readonly DependencyProperty TopRightCornerProperty =
            DependencyProperty.Register(nameof(TopRightCorner), typeof(int), typeof(AnimatedCornerRadius),
                new PropertyMetadata(0, (s, e) =>
                {
                    ((AnimatedCornerRadius)s).CornerRadius = new CornerRadius(
                        ((AnimatedCornerRadius)s).CornerRadius.TopLeft,
                        double.Parse(e.NewValue.ToString()),
                        ((AnimatedCornerRadius)s).CornerRadius.BottomRight,
                        ((AnimatedCornerRadius)s).CornerRadius.BottomLeft);
                }));

        public int BottomRightCorner
        {
            get { return (int)GetValue(BottomRightCornerProperty); }
            set { SetValue(BottomRightCornerProperty, value); }
        }
        public static readonly DependencyProperty BottomRightCornerProperty =
            DependencyProperty.Register(nameof(BottomRightCorner), typeof(int), typeof(AnimatedCornerRadius),
                new PropertyMetadata(0, (s, e) =>
                {
                    ((AnimatedCornerRadius)s).CornerRadius = new CornerRadius(
                        ((AnimatedCornerRadius)s).CornerRadius.TopLeft,
                        ((AnimatedCornerRadius)s).CornerRadius.TopRight,
                        double.Parse(e.NewValue.ToString()),
                        ((AnimatedCornerRadius)s).CornerRadius.BottomLeft);
                }));

        public int BottomLeftCorner
        {
            get { return (int)GetValue(BottomLeftCornerProperty); }
            set { SetValue(BottomLeftCornerProperty, value); }
        }
        public static readonly DependencyProperty BottomLeftCornerProperty =
            DependencyProperty.Register(nameof(BottomLeftCorner), typeof(int), typeof(AnimatedCornerRadius),
                new PropertyMetadata(0, (s, e) =>
                {
                    ((AnimatedCornerRadius)s).CornerRadius = new CornerRadius(
                        ((AnimatedCornerRadius)s).CornerRadius.TopLeft,
                        ((AnimatedCornerRadius)s).CornerRadius.TopRight,
                        ((AnimatedCornerRadius)s).CornerRadius.BottomRight,
                        double.Parse(e.NewValue.ToString()));
                }));
    }

and I define this control in MainPage and put the storyboard inside the same control and I made this storyboard ""Begin"" in code behind:

<controls:AnimatedCornerRadius

            x:Name="animatedBorder"
            Width="300"
            Height="300"
            Background="White"
            BorderBrush="Red"
            BorderThickness="8"
            CornerRadius="0"
            Tapped="animatedBorder_Tapped">
            <controls:AnimatedCornerRadius.Resources>
                <Storyboard x:Key="animatingCorners" AutoReverse="True">
                    <DoubleAnimation
                        EnableDependentAnimation="True"
                        Storyboard.TargetName="animatedBorder"
                        Storyboard.TargetProperty="TopLeftCorner"
                        From="0"
                        To="60"
                        Duration="0:0:1" />
                    <DoubleAnimation
                        EnableDependentAnimation="True"
                        Storyboard.TargetName="animatedBorder"
                        Storyboard.TargetProperty="TopRightCorner"
                        From="0"
                        To="60"
                        Duration="0:0:1" />
                    <DoubleAnimation
                        EnableDependentAnimation="True"
                        Storyboard.TargetName="animatedBorder"
                        Storyboard.TargetProperty="BottomRightCorner"
                        From="0"
                        To="60"
                        Duration="0:0:1" />
                    <DoubleAnimation
                        EnableDependentAnimation="True"
                        Storyboard.TargetName="animatedBorder"
                        Storyboard.TargetProperty="BottomLeftCorner"
                        From="0"
                        To="60"
                        Duration="0:0:1" />
                </Storyboard>
            </controls:AnimatedCornerRadius.Resources>
        </controls:AnimatedCornerRadius>

But then I think to make this properties as Attached properties to be possible to any one to implement it directly in any dependency object but then I figured out that It is impossible to animate attached properties, so I need your help to choice what is the better choice to deal with (making entirely new control to animate the corners OR there is some way else in behaviors and AnimationBuilder that can do it ????)

NOTE:
As you see, you can use these properties (TopLeftCorner, TopRightCorner, BottomRightCorner, BottomLeftCorner) as attached properties and adding it to VisualExtensions class too

Describe the solution

Making Animating CornerRadius possible using custom control

Describe alternatives you've considered

It's a good idea to add this type of animation (CornerRadiusAnimation or ThicknessAnimation) to AnimationBuilder if this possibole

Additional context & Screenshots

recordedVideo2021-12-07-232948.mp4

Codespace: dotnet process not terminating automatically

Problem

Labs is designed to be run in a GitHub Codespaces. That means when the user is able to select a Lab project from the "Run" dropdown, and upon running, build and view a sample in the browser.

However, there's a bug which prevents this from being done more than once without manually running killall dotnet or rebuilding the codespace.

Repro steps

  1. Open Labs in a Codespace
  2. Build and run a sample.
  3. Either stop the build with the "Stop" button, or refresh the page.
  4. Try to build and run again. You'll be met with an error like "address is in use".

Source code not showing on non-Windows build targets

Background

As part of #29, we are now able to pull in and show in source code for each sample, bundled as app content and pulled in via StorageFile.GetFileFromApplicationUriAsync().

However, due to a bug with Uno (filed separately here), we're unable to pull in and view the source code on any platform other than UWP and WinAppSDK.

Solution(s)

Either unoplatform/uno#8266 (see unoplatform/uno#2502 (comment)) needs to be solved, or a workaround needs to be created.

Or, as a temporary workaround, create a custom MSBuild Target that

  • Checks the head for all referenced projects
  • Checks each referenced project for any usages of
  • Manually copy the files to the project head's "Assets" folder

Then, modify all of our code to only use the Assets folder.

UWP is failing to build in release mode

From #43

The following error is preventing us from building in Release mode in the CI:

"D:\a\Labs-Windows\Labs-Windows\Toolkit.Labs.All.sln" (default target) (1:2) ->
"D:\a\Labs-Windows\Labs-Windows\Platforms\CommunityToolkit.Labs.Uwp\CommunityToolkit.Labs.Uwp.csproj" (default target) (17:6) ->
(_ComputeAppxPackagePayload target) -> 
  C:\Program Files\Microsoft Visual Studio\2022\Enterprise\MSBuild\Microsoft\VisualStudio\v17.0\AppxPackage\Microsoft.AppXPackage.Targets(1946,5): error APPX1111: Payload contains two or more files with the same destination path 'CanvasLayout.Sample\SampleOne\SamplePage.xaml', but they are different sizes. Source files:  [D:\a\Labs-Windows\Labs-Windows\Platforms\CommunityToolkit.Labs.Uwp\CommunityToolkit.Labs.Uwp.csproj]
Error: C:\Program Files\Microsoft Visual Studio\2022\Enterprise\MSBuild\Microsoft\VisualStudio\v17.0\AppxPackage\Microsoft.AppXPackage.Targets(1946,5): error APPX1111: D:\a\Labs-Windows\Labs-Windows\Labs\CanvasLayout\samples\CanvasLayout.Sample\obj\Release\uap10.0.19041\SampleOne\SamplePage.xaml [D:\a\Labs-Windows\Labs-Windows\Platforms\CommunityToolkit.Labs.Uwp\CommunityToolkit.Labs.Uwp.csproj]
Error: C:\Program Files\Microsoft Visual Studio\2022\Enterprise\MSBuild\Microsoft\VisualStudio\v17.0\AppxPackage\Microsoft.AppXPackage.Targets(1946,5): error APPX1111: D:\a\Labs-Windows\Labs-Windows\Labs\CanvasLayout\samples\CanvasLayout.Sample\SampleOne\SamplePage.xaml [D:\a\Labs-Windows\Labs-Windows\Platforms\CommunityToolkit.Labs.Uwp\CommunityToolkit.Labs.Uwp.csproj]
  C:\Program Files\Microsoft Visual Studio\2022\Enterprise\MSBuild\Microsoft\VisualStudio\v17.0\AppxPackage\Microsoft.AppXPackage.Targets(1946,5): error APPX1111: Payload contains two or more files with the same destination path 'CanvasLayout.Sample\SampleThree\SamplePage3.xaml', but they are different sizes. Source files:  [D:\a\Labs-Windows\Labs-Windows\Platforms\CommunityToolkit.Labs.Uwp\CommunityToolkit.Labs.Uwp.csproj]
Error: C:\Program Files\Microsoft Visual Studio\2022\Enterprise\MSBuild\Microsoft\VisualStudio\v17.0\AppxPackage\Microsoft.AppXPackage.Targets(1946,5): error APPX1111: D:\a\Labs-Windows\Labs-Windows\Labs\CanvasLayout\samples\CanvasLayout.Sample\obj\Release\uap10.0.19041\SampleThree\SamplePage3.xaml [D:\a\Labs-Windows\Labs-Windows\Platforms\CommunityToolkit.Labs.Uwp\CommunityToolkit.Labs.Uwp.csproj]
Error: C:\Program Files\Microsoft Visual Studio\2022\Enterprise\MSBuild\Microsoft\VisualStudio\v17.0\AppxPackage\Microsoft.AppXPackage.Targets(1946,5): error APPX1111: D:\a\Labs-Windows\Labs-Windows\Labs\CanvasLayout\samples\CanvasLayout.Sample\SampleThree\SamplePage3.xaml [D:\a\Labs-Windows\Labs-Windows\Platforms\CommunityToolkit.Labs.Uwp\CommunityToolkit.Labs.Uwp.csproj]
  C:\Program Files\Microsoft Visual Studio\2022\Enterprise\MSBuild\Microsoft\VisualStudio\v17.0\AppxPackage\Microsoft.AppXPackage.Targets(1946,5): error APPX1111: Payload contains two or more files with the same destination path 'CanvasLayout.Sample\SampleTwo\SamplePage2.xaml', but they are different sizes. Source files:  [D:\a\Labs-Windows\Labs-Windows\Platforms\CommunityToolkit.Labs.Uwp\CommunityToolkit.Labs.Uwp.csproj]
Error: C:\Program Files\Microsoft Visual Studio\2022\Enterprise\MSBuild\Microsoft\VisualStudio\v17.0\AppxPackage\Microsoft.AppXPackage.Targets(1946,5): error APPX1111: D:\a\Labs-Windows\Labs-Windows\Labs\CanvasLayout\samples\CanvasLayout.Sample\obj\Release\uap10.0.19041\SampleTwo\SamplePage2.xaml [D:\a\Labs-Windows\Labs-Windows\Platforms\CommunityToolkit.Labs.Uwp\CommunityToolkit.Labs.Uwp.csproj]
Error: C:\Program Files\Microsoft Visual Studio\2022\Enterprise\MSBuild\Microsoft\VisualStudio\v17.0\AppxPackage\Microsoft.AppXPackage.Targets(1946,5): error APPX1111: D:\a\Labs-Windows\Labs-Windows\Labs\CanvasLayout\samples\CanvasLayout.Sample\SampleTwo\SamplePage2.xaml [D:\a\Labs-Windows\Labs-Windows\Platforms\CommunityToolkit.Labs.Uwp\CommunityToolkit.Labs.Uwp.csproj]
  C:\Program Files\Microsoft Visual Studio\2022\Enterprise\MSBuild\Microsoft\VisualStudio\v17.0\AppxPackage\Microsoft.AppXPackage.Targets(1946,5): error APPX1111: Payload contains two or more files with the same destination path 'CanvasLayout.Sample\SampleTwo\SamplePageOptions.xaml', but they are different sizes. Source files:  [D:\a\Labs-Windows\Labs-Windows\Platforms\CommunityToolkit.Labs.Uwp\CommunityToolkit.Labs.Uwp.csproj]
Error: C:\Program Files\Microsoft Visual Studio\2022\Enterprise\MSBuild\Microsoft\VisualStudio\v17.0\AppxPackage\Microsoft.AppXPackage.Targets(1946,5): error APPX1111: D:\a\Labs-Windows\Labs-Windows\Labs\CanvasLayout\samples\CanvasLayout.Sample\obj\Release\uap10.0.19041\SampleTwo\SamplePageOptions.xaml [D:\a\Labs-Windows\Labs-Windows\Platforms\CommunityToolkit.Labs.Uwp\CommunityToolkit.Labs.Uwp.csproj]
Error: C:\Program Files\Microsoft Visual Studio\2022\Enterprise\MSBuild\Microsoft\VisualStudio\v17.0\AppxPackage\Microsoft.AppXPackage.Targets(1946,5): error APPX1111: D:\a\Labs-Windows\Labs-Windows\Labs\CanvasLayout\samples\CanvasLayout.Sample\SampleTwo\SamplePageOptions.xaml [D:\a\Labs-Windows\Labs-Windows\Platforms\CommunityToolkit.Labs.Uwp\CommunityToolkit.Labs.Uwp.csproj]

This needs to be fixed as soon as possible.

Codespaces: Deep linking to specific samples

Problem

Labs was designed to make it easy to view and run samples in the browser via GitHub Codespaces. We've succeeded on making that possible, but there are improvements that can be made regarding sample discovery:

  • Right now, a user must load the entire repo in a Codespace, find the sample they want, and run it.
  • If they want to see the source code, they must load the entire repo and find the files manually.

Solution

As detailed in #19:

Direct linking to specific samples may be possible, but it'll require some tinkering and research to nail down the setup

  • Separate folders can have a different devcontainer files. (Configuring separate containers).
  • Workspaces can be scoped to different folders.
  • You can link directly to a workspace in a codespace like this (see link format, clicking won't work anymore).

Add WinUI 3 Multi-target/Heads

We should also figure out about working in multi-targeting to WinUI 3 and having a WinUI 3 sample head as well I think? I'm not sure how that combines with Uno, so we may need a bit of investigation here...

Template Infrastructure

Define the basic structure of a Labs Project and produce a template so it can be easily copied and distributed.

Labs project requirements

We expect the following of resources from Labs project contributions:

  1. Library source code
  2. Sample app with various scenarios
  3. Unit Tests
  4. UI Tests
  5. Documentation

Guidance and tips

In addition to the baseline project structure, we also want to jump-start developers who use the template. The template should include additional resources such as:

  • Guidance for installing the template
    • How to: Generate a copy of the template (put in repo readme)
  • Readme document in generated template to explain:
    • What are the parts?
    • How to: Add library code
    • How to: Run the samples
    • How to: Add new samples
    • How to: Run the unit tests
    • How to: Setup WinAppDriver to run UI tests
    • How to: Add documentation
    • How to: Submit Labs project to repo
  • Working examples and helpful comments in all areas of the project (samples, tests, docs, etc.)

Template generation

To distribute the template, use the dotnet new CLI and add the configuration to the repo.

VSIX was a suggested alternative, but it doesn't support more than one project at a time. We need to be able to generate multiple projects at once.

Open questions

  • Can we include WinAppDriver via a dev dependency NuGet or something and have a pre-build that spawns it automatically to run the UI Tests?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.