Skip to content
Open
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
8 changes: 4 additions & 4 deletions components/Marquee/samples/Dependencies.props
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,21 @@
<Project>
<!-- WinUI 2 / UWP -->
<ItemGroup Condition="'$(IsUwp)' == 'true'">
<!-- <PackageReference Include="Microsoft.Toolkit.Uwp.UI.Controls.Primitives" Version="7.1.2"/> -->
<PackageReference Include="CommunityToolkit.Uwp.Behaviors" Version="8.2.250402"/>
</ItemGroup>

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

<!-- WinUI 3 / WinAppSdk -->
<ItemGroup Condition="'$(IsWinAppSdk)' == 'true'">
<!-- <PackageReference Include="CommunityToolkit.WinUI.UI.Controls.Primitives" Version="7.1.2"/> -->
<PackageReference Include="CommunityToolkit.WinUI.Behaviors" Version="8.2.250402"/>
</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"/> -->
<PackageReference Include="Uno.CommunityToolkit.WinUI.UI.Behaviors" Version="7.1.204"/>
</ItemGroup>
</Project>
6 changes: 6 additions & 0 deletions components/Marquee/samples/Marquee.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,9 @@ The default direction is left, meaning the content will move leftwards, but this
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]

# Level Up with Behaviors

Use behaviors to triggers the Marquee on events

> [!Sample MarqueeBehaviorSample]
56 changes: 56 additions & 0 deletions components/Marquee/samples/MarqueeBehaviorSample.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<!-- 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.MarqueeBehaviorSample"
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:interactivity="using:Microsoft.Xaml.Interactivity"
xmlns:local="MarqueeExperiment.Samples"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:win="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
mc:Ignorable="d">

<win:StackPanel Padding="16">
<TextBlock FontWeight="Bold"
Text="This Marquee will loop once when hovered." />
<controls:Marquee x:Name="Loop1Marquee"
Background="Transparent"
Behavior="Ticker"
Content="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."
FontSize="18"
RepeatBehavior="1x"
Speed="256">
<interactivity:Interaction.Behaviors>
<interactivity:EventTriggerBehavior EventName="PointerEntered"
SourceObject="{Binding ElementName=Loop1Marquee}">
<interactivity:CallMethodAction MethodName="StartMarquee"
TargetObject="{Binding ElementName=Loop1Marquee}" />
</interactivity:EventTriggerBehavior>
</interactivity:Interaction.Behaviors>
</controls:Marquee>

<TextBlock Margin="0,16,0,0"
FontWeight="Bold"
Text="This Marquee will loop while hovered and pause when not hovered." />
<controls:Marquee x:Name="MarqueeControl"
Background="Transparent"
Behavior="Looping"
Content="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat."
FontSize="18"
RepeatBehavior="Forever"
Speed="96">
<interactivity:Interaction.Behaviors>
<interactivity:EventTriggerBehavior EventName="PointerEntered"
SourceObject="{Binding ElementName=MarqueeControl}">
<interactivity:CallMethodAction MethodName="StartMarquee"
TargetObject="{Binding ElementName=MarqueeControl}" />
</interactivity:EventTriggerBehavior>
<interactivity:EventTriggerBehavior EventName="PointerExited"
SourceObject="{Binding ElementName=MarqueeControl}">
<interactivity:CallMethodAction MethodName="PauseMarquee"
TargetObject="{Binding ElementName=MarqueeControl}" />
</interactivity:EventTriggerBehavior>
</interactivity:Interaction.Behaviors>
</controls:Marquee>
</win:StackPanel>
</Page>
14 changes: 14 additions & 0 deletions components/Marquee/samples/MarqueeBehaviorSample.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// 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 MarqueeExperiment.Samples;

[ToolkitSample(id: nameof(MarqueeBehaviorSample), "Marquee", description: "A control for scrolling content in a marquee fashion.")]
public sealed partial class MarqueeBehaviorSample : Page
{
public MarqueeBehaviorSample()
{
this.InitializeComponent();
}
}
5 changes: 3 additions & 2 deletions components/Marquee/samples/MarqueeSample.xaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<!-- 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. -->
<!-- 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"
Expand All @@ -9,7 +9,8 @@
mc:Ignorable="d">

<StackPanel Padding="16">
<controls:Marquee Behavior="{x:Bind ConvertStringToMarqueeBehavior(MQBehavior), Mode=OneWay}"
<controls:Marquee AutoPlay="True"
Behavior="{x:Bind ConvertStringToMarqueeBehavior(MQBehavior), Mode=OneWay}"
Content="{x:Bind Data}"
Direction="{x:Bind ConvertStringToMarqueeDirection(MQDirection), Mode=OneWay}"
FontSize="18"
Expand Down
10 changes: 0 additions & 10 deletions components/Marquee/samples/MarqueeText.Samples.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,5 @@

<!-- 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>
</ItemGroup>
<ItemGroup>
<Compile Update="MarqueeSample.xaml.cs">
<DependentUpon>MarqueeSample.xaml</DependentUpon>
</Compile>
</ItemGroup>

</Project>
18 changes: 15 additions & 3 deletions components/Marquee/samples/MarqueeTextSample.xaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<!-- 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. -->
<!-- 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"
Expand All @@ -8,12 +8,24 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">

<StackPanel Padding="16">
<controls:Marquee Behavior="{x:Bind ConvertStringToMarqueeBehavior(MQBehavior), Mode=OneWay}"
<StackPanel Padding="16"
Spacing="8">
<controls:Marquee x:Name="MarqueeControl"
AutoPlay="{x:Bind MQAuto, Mode=OneWay}"
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}" />

<Button Click="StartMarquee_Click"
Content="Start Marquee" />
<Button Click="StopMarquee_Click"
Content="Stop Marquee" />
<Button Click="PauseMarquee_Click"
Content="Pause Marquee" />
<Button Click="ResumeMarquee_Click"
Content="Resume Marquee" />
</StackPanel>
</Page>
9 changes: 9 additions & 0 deletions components/Marquee/samples/MarqueeTextSample.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ namespace MarqueeExperiment.Samples;
#else
[ToolkitSampleMultiChoiceOption("MQBehavior", "Ticker", "Looping", Title = "Marquee Behavior")]
#endif
[ToolkitSampleBoolOption("MQAuto", true, Title = "Auto Play")]
public sealed partial class MarqueeTextSample : Page
{
public MarqueeTextSample()
Expand All @@ -41,4 +42,12 @@ public MarqueeTextSample()
"Down" => MarqueeDirection.Down,
_ => throw new System.NotImplementedException(),
};

private void StartMarquee_Click(object sender, RoutedEventArgs e) => MarqueeControl.StartMarquee();

private void StopMarquee_Click(object sender, RoutedEventArgs e) => MarqueeControl.StopMarquee();

private void ResumeMarquee_Click(object sender, RoutedEventArgs e) => MarqueeControl.ResumeMarquee();

private void PauseMarquee_Click(object sender, RoutedEventArgs e) => MarqueeControl.PauseMarquee();
}
52 changes: 42 additions & 10 deletions components/Marquee/src/Marquee.Events.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,23 @@ public partial class Marquee
/// <summary>
/// Event raised when the Marquee begins scrolling.
/// </summary>
public event EventHandler? MarqueeBegan;
public event EventHandler? MarqueeStarted;

/// <summary>
/// Event raised when the Marquee stops scrolling for any reason.
/// Event raised when the Marquee is stopped manually or completed.
/// </summary>
public event EventHandler? MarqueeStopped;

/// <summary>
/// Event raised when the Marquee is resumed from a pause.
/// </summary>
public event EventHandler? MarqueeResumed;

/// <summary>
/// Event raised when the Marquee is paused.
/// </summary>
public event EventHandler? MarqueePaused;

/// <summary>
/// Event raised when the Marquee completes scrolling.
/// </summary>
Expand All @@ -28,18 +38,32 @@ 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;
this.Unloaded += this.Marquee_Unloaded;

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

if (_segment1 is not null)
{
_segment1.SizeChanged += Segment_SizeChanged;
}

if (_marqueeStoryboard is not null)
{
_marqueeStoryboard.Completed += StoryBoard_Completed;
}

// Setup the animation
UpdateMarquee(false);

// The marquee should run when loaded if auto play is enabled
if (AutoPlay)
{
StartMarquee();
}
}

private void Marquee_Unloaded(object sender, RoutedEventArgs e)
Expand All @@ -53,6 +77,11 @@ private void Marquee_Unloaded(object sender, RoutedEventArgs e)
_marqueeContainer.SizeChanged -= Container_SizeChanged;
}

if (_segment1 is not null)
{
_segment1.SizeChanged -= Segment_SizeChanged;
}

if (_marqueeStoryboard is not null)
{
_marqueeStoryboard.Completed -= StoryBoard_Completed;
Expand All @@ -62,35 +91,38 @@ private void Marquee_Unloaded(object sender, RoutedEventArgs e)
private void Container_SizeChanged(object sender, SizeChangedEventArgs e)
{
if (_marqueeContainer is null)
{
return;
}

// Clip the marquee within its bounds
_marqueeContainer.Clip = new RectangleGeometry
{
Rect = new Rect(0, 0, e.NewSize.Width, e.NewSize.Height)
};

// Update animation on the fly
UpdateMarquee(true);

// The marquee should run when the size changes in case the text gets cutoff
StartMarquee();
// and auto play is enabled.
if (AutoPlay)
{
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);
UpdateMarquee(true);
}

private void StoryBoard_Completed(object? sender, object e)
{
StopMarquee(true);
StopMarquee();
MarqueeCompleted?.Invoke(this, EventArgs.Empty);
}
}
Loading
Loading