.net - sacar - hiperbola
¿Cómo hago un parpadeo de elipse? (2)
Puede hacer esto con una animación que se invierta automáticamente y se repita (esto es para Silverlight):
<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="Blinker.MainPage"
Width="640" Height="480" Loaded="UserControl_Loaded">
<UserControl.Resources>
<Storyboard x:Name="Blink" AutoReverse="True" RepeatBehavior="Forever">
<ColorAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="ellipse"
Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
<EasingColorKeyFrame KeyTime="00:00:01" Value="Gray"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
</UserControl.Resources>
<Grid x:Name="LayoutRoot" Background="White">
<Ellipse x:Name="ellipse" Fill="Green" Stroke="Black"/>
</Grid>
</UserControl>
y luego inicie la animación cuando se carga el control o cuando se establece una propiedad; no necesita una propiedad de dependencia a menos que
private bool blinking;
public bool IsBlinking
{
get
{
return blinking;
}
set
{
if (value)
{
this.Blink.Begin();
}
else
{
this.Blink.Stop();
}
this.blinking = value;
}
}
o al inicio:
private void UserControl_Loaded(object sender, System.Windows.RoutedEventArgs e)
{
this.Blink.Begin();
}
Aquí hay otra forma de hacerlo en WPF, usando VisualStateManager, que también funcionará en Silverlight:
<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
x:Class="BlinkerApp.Blinker"
x:Name="UserControl"
d:DesignWidth="100" d:DesignHeight="100">
<Grid x:Name="LayoutRoot">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="BlinkStates">
<VisualState x:Name="Blinking">
<Storyboard AutoReverse="True" RepeatBehavior="Forever">
<ColorAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="ellipse" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
<SplineColorKeyFrame KeyTime="00:00:01" Value="Gray"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Stopped"/>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Ellipse x:Name="ellipse" Fill="Green" Stroke="Black"/>
</Grid>
y luego hacer que la propiedad IsBlinking cambie el estado visual:
namespace BlinkerApp
{
using System.Windows;
using System.Windows.Controls;
/// <summary>
/// Interaction logic for Blinker.xaml
/// </summary>
public partial class Blinker : UserControl
{
private bool blinking;
public Blinker()
{
this.InitializeComponent();
}
public bool IsBlinking
{
get
{
return blinking;
}
set
{
if (value)
{
VisualStateManager.GoToState(this, "Blinking", true);
}
else
{
VisualStateManager.GoToState(this, "Stopped", true);
}
this.blinking = value;
}
}
}
}
Estoy tratando de hacer un control personalizado en WPF. Quiero que simule el comportamiento de un LED que puede parpadear.
Hay tres estados para el control: encendido, apagado y parpadeo.
Sé cómo activar y desactivar el código, pero este material de animación WPF me está volviendo loco. No puedo obtener nada para animar en absoluto. El plan es tener una propiedad llamada estado. Cuando el usuario configura el valor para que parpadee, quiero que el control alterne entre verde y gris. Supongo que necesito una propiedad de dependencia aquí, pero no tengo idea. Tenía más xaml antes pero lo borré todo. no parece hacer nada. Me encantaría hacer esto de la mejor manera posible, pero en este punto, tomaré cualquier cosa. Estoy a medio camino de escribir un hilo que cambie el color manualmente en este punto.
<UserControl x:Class="WpfAnimation.LED"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="300" Width="300">
<Grid>
<Ellipse x:Name="MyLight" Height="Auto" Width="Auto"/>
</Grid>
</UserControl>
Para permitir un mayor control de la velocidad de parpadeo y tal en su código detrás, sugiero tener un evento enrutado en su UserControl llamado Blink:
public static readonly RoutedEvent BlinkEvent = EventManager.RegisterRoutedEvent("Blink", RoutingStrategy.Direct, typeof(RoutedEventHandler), typeof(LedControl));
public event RoutedEventHandler Blink
{
add { AddHandler(BlinkEvent, value); }
remove { RemoveHandler(BlinkEvent, value); }
}
En el código que se encuentra detrás, puede configurar un temporizador para plantear el evento con la frecuencia que desee (esto también le brinda la oportunidad de parpadear la luz una vez siempre que lo desee:
RaiseEvent(new RoutedEventArgs(LedControl.Blink));
Ahora en XAML, el siguiente código haría visible un resplandor, y establezca la propiedad de relleno de su elipse (ledEllipse) en un degradado radial verde brillante, luego regrese el valor de relleno a un verde oscuro apagado (que podría cambiar a gris Si te gusta). Simplemente puede cambiar la duración para que el parpadeo dure más tiempo.
<UserControl.Triggers>
<EventTrigger RoutedEvent="local:LedControl.Blink">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="glow"
Storyboard.TargetProperty="Opacity"
To="100"
AutoReverse="True"
Duration="0:0:0.075" />
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ledEllipse"
Storyboard.TargetProperty="Fill"
Duration="0:0:0.15">
<ObjectAnimationUsingKeyFrames.KeyFrames>
<DiscreteObjectKeyFrame KeyTime="0:0:0.01">
<DiscreteObjectKeyFrame.Value>
<RadialGradientBrush>
<!--bright Green Brush-->
<GradientStop Color="#FF215416" Offset="1"/>
<GradientStop Color="#FE38DA2E" Offset="0"/>
<GradientStop Color="#FE81FF79" Offset="0.688"/>
</RadialGradientBrush>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
<DiscreteObjectKeyFrame KeyTime="0:0:0.15" >
<DiscreteObjectKeyFrame.Value>
<RadialGradientBrush>
<!--dim Green Brush-->
<GradientStop Color="#FF21471A" Offset="1"/>
<GradientStop Color="#FF33802F" Offset="0"/>
<GradientStop Color="#FF35932F" Offset="0.688"/>
</RadialGradientBrush>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames.KeyFrames>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</UserControl.Triggers>
Además, me estoy refiriendo directamente a la elipse ''ledEllipse'' y su correspondiente DropShadowEffect ''glow'' que se define en el ledControl de la siguiente manera (redLight es simplemente otro pincel de degradado radial en el que inicio la propiedad de relleno de mi led):
<Ellipse x:Name="statusLight" Height="16" Width="16" Margin="0" Fill="{DynamicResource redLight}" >
<Ellipse.Effect>
<DropShadowEffect x:Name="glow" ShadowDepth="0" Color="Lime" BlurRadius="10" Opacity="0" />
</Ellipse.Effect>
</Ellipse>
Nota: DropShadowEffect se introdujo en .Net 3.5, pero puede eliminarlo si no desea un efecto de brillo (pero se ve bien en un fondo de contraste de color sólido).