-
|
Similar to #4673 I would like to start an animation on button pressed. I first tried this: Note: <ucp:MenuActionItem Width="{StaticResource MenuViewMenuItemWidth}"
Height="{StaticResource MenuViewMenuItemHeight}"
PathIconData="{StaticResource CameraPath}"
Command="{Binding CreateScreenshotCommand}" >
<ucp:MenuActionItem.Styles>
<Style Selector=":pressed /template/ Border#PART_Border">
<Style.Animations>
<Animation Duration="0:0:1.000">
<KeyFrame Cue="0%">
<Setter Property="Background" Value="LightBlue"></Setter>
</KeyFrame>
<KeyFrame Cue="100%">
<Setter Property="Background" Value="Black"></Setter>
</KeyFrame>
</Animation>
</Style.Animations>
</Style>
</ucp:MenuActionItem.Styles>
</ucp:MenuActionItem>... resulting in the correct animation... but of course only if you keep the button pressed. This is shown in the video below. First 2 clicks keep the butten pressed. Second 2 clicks release the button immediately, hence, the animation stops. PixrBunion.-.Microsoft.Visual.Studio.2023-04-12.12-57-48.mp4As above I use my own templated control derived from button, hence, there would be room to add styled properties, pseudo classes, ... What would be the best approach to allow for Xaml-defined animations that are initiated on :pressed but endure the unpressed event? |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment
-
|
This is what I did (because I have my own templated control:
Code Behind: public static readonly StyledProperty<TimeSpan> PressedAnimationStateDurationProperty =
AvaloniaProperty.Register<MenuActionItem, TimeSpan>(nameof(PressedAnimationStateDurationProperty), TimeSpan.Zero);
public TimeSpan PressedAnimationStateDuration
{
get { return GetValue(PressedAnimationStateDurationProperty); }
set
{
SetValue(PressedAnimationStateDurationProperty, value);
UpdatePressedAnimationTimer(value);
}
}
private const string PressedAnimationState = ":pressedAnimation";
private readonly DispatcherTimer _pressedAnimationStateTimer;
public MenuActionItem()
{
_pressedAnimationStateTimer = new DispatcherTimer(DispatcherPriority.Background)
{
Interval = PressedAnimationStateDuration,
};
_pressedAnimationStateTimer.Tick += OnPressedAnimationStateTimerTick;
}
private void UpdatePressedAnimationTimer(TimeSpan duration)
{
if (duration > TimeSpan.Zero)
{
if (_pressedAnimationStateTimer != null)
{
_pressedAnimationStateTimer.Stop();
_pressedAnimationStateTimer.Interval = duration;
}
}
}
private void StartPressedAnimationTimer()
{
if (_pressedAnimationStateTimer != null)
{
_pressedAnimationStateTimer.Start();
}
}
private void StopPressedAnimationTimer()
{
if (_pressedAnimationStateTimer != null)
{
_pressedAnimationStateTimer.Stop();
}
}
private void AddPressedAnimationState()
{
RemovePressedAnimationState();
PseudoClasses.Add(PressedAnimationState);
}
private void RemovePressedAnimationState()
{
if (PseudoClasses.Contains(PressedAnimationState))
{
PseudoClasses.Remove(PressedAnimationState);
}
}
private void OnPressedAnimationStateTimerTick(object sender, EventArgs e)
{
StopPressedAnimationTimer();
RemovePressedAnimationState();
}
protected override void OnPointerPressed(PointerPressedEventArgs e)
{
if (PressedAnimationStateDuration > TimeSpan.Zero)
{
AddPressedAnimationState();
StartPressedAnimationTimer();
}
base.OnPointerPressed(e);
}Using in a user control: <ucp:MenuActionItem Width="{StaticResource MenuViewMenuItemWidth}"
Height="{StaticResource MenuViewMenuItemHeight}"
PathIconData="{StaticResource CameraPath}"
Command="{Binding CreateScreenshotCommand}"
PressedAnimationStateDuration="0:0:1">
<ucp:MenuActionItem.Styles>
<Style Selector=":pressedAnimation /template/ Border#PART_Border">
<Style.Animations>
<Animation Duration="0:0:1.000">
<KeyFrame Cue="0%">
<Setter Property="Background" Value="{StaticResource BackgroundHighlightedDefault}"/>
</KeyFrame>
<KeyFrame Cue="100%">
<Setter Property="Background" Value="{StaticResource BackgroundDefault}"/>
</KeyFrame>
</Animation>
</Style.Animations>
</Style>
</ucp:MenuActionItem.Styles>
</ucp:MenuActionItem>Not super pretty, not super generic but at least generic enough to start any kind of animation on pressed for how ever long you want. |
Beta Was this translation helpful? Give feedback.
This is what I did (because I have my own templated control:
TimeSpan PressedAnimationStateDurationDispatcherTimerCode Behind: