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
2 changes: 1 addition & 1 deletion ReadMe.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ Otherwise, you can clone the repo, open the `components` directory, navigate wit
- [DataTable](https://github.com/CommunityToolkit/Labs-Windows/blob/main/components/DataTable/samples/DataTable.md)
- [Extensions.DependencyInjection](https://github.com/CommunityToolkit/Labs-Windows/tree/main/components/Extensions.DependencyInjection)
- [MarkdownTextBlock](https://github.com/CommunityToolkit/Labs-Windows/blob/main/components/MarkdownTextBlock/samples/MarkdownTextBlock.md)
- [MarqueeText](https://github.com/CommunityToolkit/Labs-Windows/blob/main/components/MarqueeText/samples/MarqueeText.md)
- [Marquee](https://github.com/CommunityToolkit/Labs-Windows/blob/main/components/Marquee/samples/Marquee.md)
- [Notifications](https://github.com/CommunityToolkit/Labs-Windows/tree/main/components/Notifications)
- [Ribbon](https://github.com/CommunityToolkit/Labs-Windows/blob/main/components/Ribbon/samples/Ribbon.md)
- [RivePlayer](https://github.com/CommunityToolkit/Labs-Windows/blob/main/components/RivePlayer/samples/RivePlayer.md)
Expand Down
52 changes: 52 additions & 0 deletions components/Marquee/samples/Marquee.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
---
title: Marquee
author: Avid29
description: A control for scrolling content in a marquee fashion.
keywords: Marquee, Control
dev_langs:
- csharp
category: Controls
subcategory: Layout
experimental: true
discussion-id: 231
issue-id: 426
icon: Assets/Marquee.png
---

The Marquee control allows text or other content to scroll in a marquee fashion. The control is heavily templated and many changes can be made by modifying the style. The control can also be adjusted using the Speed, Behavior, RepeatBehavior, and Direction properties.

## Speed

The speed property determines how quickly the content moves in pixels per second. The speed can be adjusted mid-animation and handled continously.

## Behavior

The Marquee control has 3 behaviors

### Ticker

Ticker mode starts with all content off the screen then scrolls the content across across the screen. When the animation finishes in the mode no content will be on screen.

### Looping

Looping mode will begin with the start of the content fully in frame then scroll towards the end. When the end is reached it will loop back to the start of the content. Nothing will happen if the content fits in frame.

### Bouncing

Looping mode will begin with the start of the content fully in frame then scroll towards the end. When the end is reached it will bounce and scroll backwards to the start of the content. Nothing will happen if the content fits in frame.

## RepeatBehavior

The repeat behavior determines how many times the marquee will loop before the animation finishes. It can be a number of iteration, a duration, or forever.

## Direction

The default direction is left, meaning the content will move leftwards, but this can be changed to right, up, or down. Direction changed between left and right or up and down are handled continously, meaning that the animation will resume from its current position if changed between these directions.

> [!Sample MarqueeTextSample]

## Non-Text Content

It is possible to use non-text content in the Marquee control. However templating must be used because the control will need to be duplicated for the looping animation.

> [!Sample MarqueeSample]
44 changes: 44 additions & 0 deletions components/Marquee/samples/MarqueeSample.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<!-- 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. -->
<Page x:Class="MarqueeExperiment.Samples.MarqueeSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="using:CommunityToolkit.WinUI.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:MarqueeExperiment.Samples"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">

<StackPanel Padding="16">
<controls:Marquee Behavior="{x:Bind ConvertStringToMarqueeBehavior(MQBehavior), Mode=OneWay}"
Content="{x:Bind Data}"
Direction="{x:Bind ConvertStringToMarqueeDirection(MQDirection), Mode=OneWay}"
FontSize="18"
RepeatBehavior="Forever"
Speed="{x:Bind MQSpeed, Mode=OneWay}">
<controls:Marquee.ContentTemplate>
<DataTemplate x:DataType="local:MarqueeSampleItems">
<ItemsControl ItemsSource="{x:Bind Items}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"
Spacing="8" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate x:DataType="local:MarqueeSampleItem">
<Border Width="100"
Height="48"
Background="{x:Bind Brush}">
<TextBlock Text="{x:Bind Name}" />
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</DataTemplate>
</controls:Marquee.ContentTemplate>
</controls:Marquee>

<Button Click="AddItem_Click"
Content="Add something" />
</StackPanel>
</Page>
73 changes: 73 additions & 0 deletions components/Marquee/samples/MarqueeSample.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
// 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.Controls;
using Windows.UI;

namespace MarqueeExperiment.Samples;

[ToolkitSample(id: nameof(MarqueeSample), "Marquee", description: "A control for scrolling content in a marquee fashion.")]
[ToolkitSampleNumericOption("MQSpeed", initial: 96, min: 48, max: 196, step: 1, Title = "Speed")]
[ToolkitSampleMultiChoiceOption("MQDirection", "Left", "Right", "Up", "Down", Title = "Marquee Direction")]
//[ToolkitSampleMultiChoiceOption("MarqueeRepeat", "Repeat", "Forever", "1x", "2x")]
#if !HAS_UNO
[ToolkitSampleMultiChoiceOption("MQBehavior", "Ticker", "Looping", "Bouncing", Title = "Marquee Behavior")]
#else
[ToolkitSampleMultiChoiceOption("MQBehavior", "Ticker", "Looping", Title = "Marquee Behavior")]
#endif
public sealed partial class MarqueeSample : Page
{
public MarqueeSample()
{
this.InitializeComponent();

for (int i = 0; i < 15; i++)
{
AddItem_Click(this, null);
}
}

private MarqueeBehavior ConvertStringToMarqueeBehavior(string str) => str switch
{
"Looping" => MarqueeBehavior.Looping,
"Ticker" => MarqueeBehavior.Ticker,
#if !HAS_UNO
"Bouncing" => MarqueeBehavior.Bouncing,
#endif
_ => throw new NotImplementedException(),
};

public MarqueeSampleItems Data = new();

private MarqueeDirection ConvertStringToMarqueeDirection(string str) => str switch
{
"Left" => MarqueeDirection.Left,
"Up" => MarqueeDirection.Up,
"Right" => MarqueeDirection.Right,
"Down" => MarqueeDirection.Down,
_ => throw new NotImplementedException(),
};

private void AddItem_Click(object sender, RoutedEventArgs? e)
{
var rand = new Random();
Data.Items.Add(new MarqueeSampleItem()
{
Name = $"Item {Data.Items.Count + 1}",
Brush = new SolidColorBrush(Color.FromArgb(255, (byte)rand.Next(256), (byte)rand.Next(256), (byte)rand.Next(256))),
});
}
}

public class MarqueeSampleItems
{
public ObservableCollection<MarqueeSampleItem> Items { get; } = new();
}

public record MarqueeSampleItem
{
public string? Name { get; set; }

public Brush? Brush { get; set; }
}
Original file line number Diff line number Diff line change
@@ -1,25 +1,20 @@
<Project>
<Import Project="$([MSBuild]::GetPathOfFileAbove(Directory.Build.props))" Condition="Exists('$([MSBuild]::GetPathOfFileAbove(Directory.Build.props))')" />
<PropertyGroup>
<ToolkitComponentName>MarqueeText</ToolkitComponentName>
<ToolkitComponentName>Marquee</ToolkitComponentName>
</PropertyGroup>

<!-- Sets this up as a toolkit component's sample project -->
<Import Project="$(ToolingDirectory)\ToolkitComponent.SampleProject.props" />
<ItemGroup>
<Compile Update="MarqueeTextSample.xaml.cs">
<DependentUpon>MarqueeTextSample.xaml</DependentUpon>
</Compile>

<UpToDateCheckInput Remove="MarqueeTextSample.xaml" />
</ItemGroup>

<!-- Sets this up as a toolkit component's sample project -->
<Import Project="$(ToolingDirectory)\ToolkitComponent.SampleProject.props" />

<ItemGroup>
<None Remove="Assets\MarqueeText.png" />

<Content Include="Assets\MarqueeText.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Compile Update="MarqueeSample.xaml.cs">
<DependentUpon>MarqueeSample.xaml</DependentUpon>
</Compile>
</ItemGroup>

</Project>
19 changes: 19 additions & 0 deletions components/Marquee/samples/MarqueeTextSample.xaml
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. -->
<Page x:Class="MarqueeExperiment.Samples.MarqueeTextSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="using:CommunityToolkit.WinUI.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="MarqueeExperiment.Samples"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">

<StackPanel Padding="16">
<controls:Marquee Behavior="{x:Bind ConvertStringToMarqueeBehavior(MQBehavior), Mode=OneWay}"
Content="{x:Bind MQText, Mode=OneWay}"
Direction="{x:Bind ConvertStringToMarqueeDirection(MQDirection), Mode=OneWay}"
FontSize="18"
RepeatBehavior="Forever"
Speed="{x:Bind MQSpeed, Mode=OneWay}" />
</StackPanel>
</Page>
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@

using CommunityToolkit.WinUI.Controls;

namespace MarqueeTextExperiment.Samples;
[ToolkitSample(id: nameof(MarqueeTextSample), "MarqueeText", description: "A control for scrolling text in a marquee fashion.")]
namespace MarqueeExperiment.Samples;

[ToolkitSample(id: nameof(MarqueeTextSample), "Marquee", description: "A control for scrolling content in a marquee fashion.")]
[ToolkitSampleNumericOption("MQSpeed", initial: 96, min: 48, max: 196, step: 1, Title = "Speed")]
[ToolkitSampleMultiChoiceOption("MQDirection", "Left", "Right", "Up", "Down", Title = "Marquee Direction")]
[ToolkitSampleTextOption("MQText", "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.")]
//[ToolkitSampleMultiChoiceOption("MarqueeRepeat", "Repeat", "Forever", "1x", "2x")]
#if !HAS_UNO
[ToolkitSampleMultiChoiceOption("MQBehavior", "Ticker", "Looping", "Bouncing", Title = "Marquee Behavior")]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,13 @@
<Project>
<Import Project="$([MSBuild]::GetPathOfFileAbove(Directory.Build.props))" Condition="Exists('$([MSBuild]::GetPathOfFileAbove(Directory.Build.props))')" />
<PropertyGroup>
<ToolkitComponentName>MarqueeText</ToolkitComponentName>
<Description>This package contains MarqueeText.</Description>
<ToolkitComponentName>Marquee</ToolkitComponentName>
<Description>This package contains Marquee.</Description>

<!-- Rns suffix is required for namespaces shared across projects. See https://github.com/CommunityToolkit/Labs-Windows/issues/152 -->
<RootNamespace>CommunityToolkit.WinUI.Controls.MarqueeTextRns</RootNamespace>
<RootNamespace>CommunityToolkit.WinUI.Controls.MarqueeRns</RootNamespace>
</PropertyGroup>

<ItemGroup>
<UpToDateCheckInput Remove="MarqueeText.xaml" />
</ItemGroup>

<!-- Sets this up as a toolkit component's source project -->
<Import Project="$(ToolingDirectory)\ToolkitComponent.SourceProject.props" />

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ namespace CommunityToolkit.WinUI.Controls;
/// <summary>
/// A Control that displays Text in a Marquee style.
/// </summary>
public partial class MarqueeText
public partial class Marquee
{
/// <summary>
/// Event raised when the Marquee begins scrolling.
Expand All @@ -23,10 +23,30 @@ public partial class MarqueeText
/// Event raised when the Marquee completes scrolling.
/// </summary>
public event EventHandler? MarqueeCompleted;

private void Marquee_Loaded(object sender, RoutedEventArgs e)
{
// While loaded, detach the loaded event and attach the unloaded event
this.Loaded -= this.Marquee_Loaded;
this.Unloaded += Marquee_Unloaded;

// Attach other events
if (_marqueeContainer is not null)
{
_marqueeContainer.SizeChanged += Container_SizeChanged;
}

private void MarqueeText_Unloaded(object sender, RoutedEventArgs e)
if (_marqueeStoryboard is not null)
{
_marqueeStoryboard.Completed += StoryBoard_Completed;
}
}

private void Marquee_Unloaded(object sender, RoutedEventArgs e)
{
this.Unloaded -= MarqueeText_Unloaded;
// Restore the loaded event and detach the unloaded event
this.Loaded += Marquee_Loaded;
this.Unloaded -= Marquee_Unloaded;

if (_marqueeContainer is not null)
{
Expand Down Expand Up @@ -56,6 +76,18 @@ private void Container_SizeChanged(object sender, SizeChangedEventArgs e)
StartMarquee();
}

private void Segment_SizeChanged(object sender, SizeChangedEventArgs e)
{
if (_segment1 is null)
{
return;
}

// If the segment size changes, we need to update the storyboard,
// and seek to the correct position to maintain a smooth animation.
UpdateAnimation(true);
}

private void StoryBoard_Completed(object? sender, object e)
{
StopMarquee(true);
Expand Down
Loading
Loading