Mar*_*ins 1 xaml uwp windows-10-universal uwp-xaml
在 WPF 中,我可以创建一个故事板作为页面/控件资源,然后多次将其用于该页面(或父控件)内的控件...
<Grid Background="{DynamicResource CorporateLogoBackgroundBrush}" views:MainWindowHelper.DragWindowOnMouseDown="True">
<Grid.Resources>
<Storyboard x:Key="FlashRedBackgroundStoryboard">
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Duration="0:0:1" RepeatBehavior="Forever">
<ObjectAnimationUsingKeyFrames.KeyFrames>
<DiscreteObjectKeyFrame KeyTime="0:0:0.5">
<DiscreteObjectKeyFrame.Value>
<SolidColorBrush Color="Red" />
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames.KeyFrames>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</Grid.Resources>
<Border Grid.Column="4" BorderThickness="0">
<Border.Style>
<Style TargetType="{x:Type Border}">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=IsNetworkConnectivityOk}" Value="false">
<DataTrigger.EnterActions>
<BeginStoryboard Name="FlashRedBackgroundStoryboard">
<StaticResource ResourceKey="FlashRedBackgroundStoryboard" />
</BeginStoryboard>
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<StopStoryboard BeginStoryboardName="FlashRedBackgroundStoryboard"></StopStoryboard>
</DataTrigger.ExitActions>
</DataTrigger>
</Style.Triggers>
</Style>
</Border.Style>
<TextBlock Text="LAN/WLAN" />
</Border>
<Border Grid.Column="5" BorderThickness="0">
<Border.Style>
<Style TargetType="{x:Type Border}">
<Setter Property="Background" Value="{DynamicResource CorporateLogoBackgroundBrush}" />
<Style.Triggers>
<DataTrigger Binding="{Binding Path=SynchronisationClientService.IsActive}" Value="true">
<Setter Property="Background" Value="Green" />
</DataTrigger>
<DataTrigger Binding="{Binding Path=SynchronisationClientService.IsRunning}" Value="false">
<DataTrigger.EnterActions>
<BeginStoryboard Name="FlashRedBackgroundStoryboard">
<StaticResource ResourceKey="FlashRedBackgroundStoryboard" />
</BeginStoryboard>
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<StopStoryboard BeginStoryboardName="FlashRedBackgroundStoryboard"></StopStoryboard>
</DataTrigger.ExitActions>
</DataTrigger>
</Style.Triggers>
</Style>
</Border.Style>
<TextBlock Text="SYNC" />
</Border>
</Grid>
Run Code Online (Sandbox Code Playgroud)
但是,我找不到在 UWP 中执行相同操作的方法。在 WPF 中使用 DataTrigger 和 BeginStoryboard 似乎会自动关联 Storyboard.TargetName,但在 UWP 中,我必须使用交互包,然后尝试以相同的方式将故事板与控件关联,因为故事板未与控件关联。 ..
<Grid Background="{StaticResource CorporateBackgroundBrush}">
<Grid.Resources>
<Storyboard x:Key="FlashRedBackgroundStoryboard">
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Duration="0:0:1" RepeatBehavior="Forever">
<ObjectAnimationUsingKeyFrames.KeyFrames>
<DiscreteObjectKeyFrame KeyTime="0:0:0.5">
<DiscreteObjectKeyFrame.Value>
<SolidColorBrush Color="Red" />
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames.KeyFrames>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</Grid.Resources>
<Border Grid.Column="4" BorderThickness="0">
<interactivity:Interaction.Behaviors>
<interactionsCore:DataTriggerBehavior Binding="{Binding IsNetworkConnectivityOk}" ComparisonCondition="Equal" Value="false">
<media:ControlStoryboardAction Storyboard="{StaticResource FlashRedBackgroundStoryboard}" />
</interactionsCore:DataTriggerBehavior>
</interactivity:Interaction.Behaviors>
<TextBlock Text="LAN/WLAN" />
</Border>
<Border Grid.Column="5" BorderThickness="0">
<interactivity:Interaction.Behaviors>
<interactionsCore:DataTriggerBehavior Binding="{Binding IsNetworkConnectivityOk}" ComparisonCondition="Equal" Value="false">
<media:ControlStoryboardAction Storyboard="{StaticResource FlashRedBackgroundStoryboard}" />
</interactionsCore:DataTriggerBehavior>
</interactivity:Interaction.Behaviors>
<TextBlock Text="SYNC" />
</Border>
</Grid>
Run Code Online (Sandbox Code Playgroud)
我能找到在 UWP 中执行此操作的唯一方法是拥有多个相同的故事板,每个故事板都有对其将影响的控件的引用。
<Grid Background="{StaticResource CorporateBackgroundBrush}">
<Grid.Resources>
<Storyboard x:Name="NetworkConnectivityStoryboard">
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="NetworkConnectivityBorder" Storyboard.TargetProperty="Background" Duration="0:0:1" RepeatBehavior="Forever">
<ObjectAnimationUsingKeyFrames.KeyFrames>
<DiscreteObjectKeyFrame KeyTime="0:0:0.5">
<DiscreteObjectKeyFrame.Value>
<SolidColorBrush Color="Red" />
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames.KeyFrames>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Name="SynchronisationStatusStoryboard">
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="SynchronisationStatusBorder" Storyboard.TargetProperty="Background" Duration="0:0:1" RepeatBehavior="Forever">
<ObjectAnimationUsingKeyFrames.KeyFrames>
<DiscreteObjectKeyFrame KeyTime="0:0:0.5">
<DiscreteObjectKeyFrame.Value>
<SolidColorBrush Color="Red" />
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames.KeyFrames>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</Grid.Resources>
<Border x:Name="NetworkConnectivityBorder" Grid.Column="4" BorderThickness="0">
<interactivity:Interaction.Behaviors>
<interactionsCore:DataTriggerBehavior Binding="{Binding IsNetworkConnectivityOk}" ComparisonCondition="Equal" Value="false">
<media:ControlStoryboardAction Storyboard="{StaticResource NetworkConnectivityStoryboard}" />
</interactionsCore:DataTriggerBehavior>
</interactivity:Interaction.Behaviors>
<TextBlock Text="LAN/WLAN" />
</Border>
<Border x:Name="SynchronisationStatusBorder" Grid.Column="5" BorderThickness="0">
<interactivity:Interaction.Behaviors>
<interactionsCore:DataTriggerBehavior Binding="{Binding IsSynchronisingk}" ComparisonCondition="Equal" Value="false">
<media:ControlStoryboardAction Storyboard="{StaticResource SynchronisationStatusStoryboard}" />
</interactionsCore:DataTriggerBehavior>
</interactivity:Interaction.Behaviors>
<TextBlock Text="SYNC" />
</Border>
</Grid>
Run Code Online (Sandbox Code Playgroud)
有没有一种方法可以共享故事板,以便它可以针对多个控件使用(在这个特定实例中,它是一个状态栏,当关联的视图模型属性具有特定值时,某些元素需要闪烁。我不敢相信我实际上必须创建多个重复的对象才能实现此目的。
谢谢。
在 UWP 中,一次Storyboard只能为一个动画制作动画。 Target因此从技术上讲,您可以手动停止(即Storyboard.Stop)它,更改其Target属性并再次启动动画(即Storyboard.Begin)。
但是如果您想同时为两个元素设置动画该怎么办?那么这个方法就行不通了。Storyboard这就是为什么为每个要设置动画的元素创建一个新元素是有意义的。
下面是使用附加属性而不是静态 XAML 的解决方案。需要编写一些代码,但是一旦设置完毕,它就非常易于使用(即一行 XAML 代码)并且几乎适用于任何元素。
这个想法是创建一个bool名为 的属性ShowFlashBackground,该属性可以附加到具有Background属性(例如Border、Grid或 any )的元素Control。
然后,每当此属性设置为(例如由其true触发)时,调用扩展方法来启动彩色动画。IsNetworkConnectivityOkFlashElementBackground
代码
public static class Util
{
public static void SetShowFlashBackground(DependencyObject element, bool value)
{
element.SetValue(ShowFlashBackgroundProperty, value);
}
public static bool GetShowFlashBackground(DependencyObject element)
{
return (bool)element.GetValue(ShowFlashBackgroundProperty);
}
public static readonly DependencyProperty ShowFlashBackgroundProperty = DependencyProperty.RegisterAttached(
"ShowFlashBackground", typeof(bool), typeof(Util), new PropertyMetadata(true, (s, e) =>
{
if ((bool)e.NewValue)
{
var self = (FrameworkElement)s;
self.FlashElementBackground();
// Rest the value back to false so the callback can be triggered again.
SetShowFlashBackground(self, false);
}
}));
public static void FlashElementBackground(this FrameworkElement element)
{
string elementTypeName;
switch (element)
{
case Border border:
elementTypeName = "Border";
if (border.Background == null) border.Background = new SolidColorBrush(Colors.Transparent);
break;
case Panel panel:
elementTypeName = "Panel";
if (panel.Background == null) panel.Background = new SolidColorBrush(Colors.Transparent);
break;
case Control control:
elementTypeName = "Control";
if (control.Background == null) control.Background = new SolidColorBrush(Colors.Transparent);
break;
// More case statements can be added here to cover more scenarios...
default:
return;
}
var colorAnimation = new ColorAnimationUsingKeyFrames();
var keyFrame1 = new LinearColorKeyFrame { KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromMilliseconds(0)), Value = Colors.Transparent };
var keyFrame2 = new LinearColorKeyFrame { KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromMilliseconds(500)), Value = Colors.Red };
colorAnimation.KeyFrames.Add(keyFrame1);
colorAnimation.KeyFrames.Add(keyFrame2);
Storyboard.SetTarget(colorAnimation, element);
Storyboard.SetTargetProperty(colorAnimation, $"({elementTypeName}.Background).(SolidColorBrush.Color)");
var storyboard = new Storyboard
{
RepeatBehavior = RepeatBehavior.Forever,
AutoReverse = true
};
storyboard.Children.Add(colorAnimation);
storyboard.Begin();
}
}
Run Code Online (Sandbox Code Playgroud)
XAML
<Border local:Util.ShowFlashBackground="{Binding IsNetworkConnectivityOk}">
<TextBlock Text="LAN/WLAN" />
</Border>
<Border local:Util.ShowFlashBackground="{Binding IsSynchronisingOk}"
Grid.Column="1">
<TextBlock Text="SYNC" />
</Border>
Run Code Online (Sandbox Code Playgroud)
希望这可以帮助!
| 归档时间: |
|
| 查看次数: |
967 次 |
| 最近记录: |