gpt4 book ai didi

c# - 如何在不丢失原始颜色轨迹的情况下使背景颜色动画为新颜色并返回?

转载 作者:太空狗 更新时间:2023-10-30 01:19:53 25 4
gpt4 key购买 nike

所以我正在尝试创建一个简单的动画,使背景从初始颜色变为新颜色并返回。

我遇到的最初问题是,我在触发动画的 MouseDownEvent 上创建了一个触发器,但用户可以在第一个动画完成之前触发另一个动画。这个新动画将从当前的阴影动画到新的颜色并返回。通过在动画进行时逐渐重新启动动画,原始颜色会丢失。

解决这个问题的最简单方法可能是我将完成的事件用于动画。但是,我不喜欢这个解决方案,因为我希望我的动画在资源字典中采用自定义样式,而不是控件本身的一部分。如果动画是资源字典中的自定义样式,那么它将无法访问控件本身的代码。有没有一种好的方法可以让动画工作同时保持样式和控件之间的分离?

然后我有了不同的想法。错误是因为我从 border.background.color 到新颜色再返回动画,因此如果我在旧动画运行时开始新动画,则新动画从先前动画所在的任何颜色值开始。但是,如果我将动画设置为返回原始背景颜色的某些已保存属性值,那么即使用户重新启动动画,我也不会有问题。

 <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Components="clr-namespace:DaedalusGraphViewer.Components"
xmlns:Converters="clr-namespace:DaedalusGraphViewer.Components.Converters"
>
<Converters:ThicknessToLeftThicknessConverter x:Key="ThicknessToLeftThicknessConverter" />

<Style x:Key="SearchBoxListViewItemStyle" TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="LightBlue" />
</Trigger>
</Style.Triggers>
</Style>


<Style x:Key="{x:Type Components:SearchBox}" TargetType="{x:Type Components:SearchBox}">
<Style.Resources>

</Style.Resources>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Components:SearchBox}">
<Border x:Name="Border"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<Grid x:Name="LayoutGrid">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />

</Grid.ColumnDefinitions>
<ScrollViewer
x:Name="PART_ContentHost"
Grid.Column="0"
VerticalAlignment="Center"
/>
<Label
x:Name="DefaultTextLabel"
Grid.Column="0"
Foreground="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TextColor}"
Content="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=LabelText}"
VerticalAlignment="Center"
FontStyle="Italic"
/>




<Popup x:Name="RecentSearchesPopup"
IsOpen="False"
>
<ListView
x:Name="PreviousSearchesListView"
ListView.ItemContainerStyle="{StaticResource SearchBoxListViewItemStyle}"
>
</ListView>
</Popup>

<Border
x:Name="PreviousSearchesBorder"
Grid.Column="2"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Background="LightGray"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=BorderThickness,
Converter={StaticResource ThicknessToLeftThicknessConverter}}"
>
<Image
x:Name="PreviousSearchesIcon"
ToolTip="Previous Searches"
Width="15"
Height="15"
Stretch="Uniform"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Source="pack://application:,,,/DaedalusGraphViewer;component/Images/Previous.png"
/>
</Border>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="HasText" Value="True">
<Setter Property="Visibility" TargetName="DefaultTextLabel" Value="Hidden" />
</Trigger>
<Trigger
SourceName="DefaultTextLabel"
Property="IsMouseOver"
Value="True"
>
<Setter Property="Cursor" Value="IBeam" />
</Trigger>

<!--<EventTrigger RoutedEvent="Mouse.MouseDown" SourceName="PreviousSearchesBorder">
<BeginStoryboard>
<Storyboard>
<ColorAnimation
AutoReverse="True"
Duration="0:0:0.2"
Storyboard.TargetName="PreviousSearchesBorder"
Storyboard.TargetProperty="(Border.Background).Color"
To="Black"
/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>-->


<Trigger Property="IsPopupOpening" Value="True">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimationUsingKeyFrames
Storyboard.TargetName="PreviousSearchesBorder"
Storyboard.TargetProperty="(Border.Background).Color"
>
<LinearColorKeyFrame KeyTime="0:0:0.0" Value="{x:Static Components:SearchBox.DefaultRecentSearchesButtonColor}" />
<LinearColorKeyFrame KeyTime="0:0:0.2" Value="Black" />
<LinearColorKeyFrame KeyTime="0:0:0.4" Value="{x:Static Components:SearchBox.DefaultRecentSearchesButtonColor}" />
</ColorAnimationUsingKeyFrames>
<!--<ColorAnimation
AutoReverse="True"
Duration="0:0:0.2"
Storyboard.TargetName="PreviousSearchesBorder"
Storyboard.TargetProperty="(Border.Background).Color"
To="Black"
/>-->
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
</Trigger>

但是,为了做到这一点,我需要存储原始背景属性,但我还没有让它工作。我不能使用绑定(bind),因为动画中的属性必须是可卡住的,所以我尝试在控件上创建一个静态属性,该属性在控件的加载事件中设置为原始值。

我在后面的代码中将颜色设置为背景色,但样式并未反射(reflect)该属性。

我在 xaml 中的静态引用是否正确?如果是这样,那么当样式应该从静态引用加载颜色时不是 onapplytemplate 吗?

最佳答案

好吧,你不能在没有卡住错误的情况下使用 DynamicResource。

如果您在运行时加载 Xaml 文件并将 StaticResource 添加到 Xaml 文件会怎样?

这是一个例子。 (我对 Xaml 文件进行了一些快速而肮脏的解析,但它适用于概念验证。)

将 StoryBoardResourceDictionary.xaml 的属性更改为 Content 和 Copy(如果较新)并删除 MSBuild:Compile 设置。

StoryBoardResourceDictionary.xaml

<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style x:Key="WindowWithTrigger" TargetType="Window">
<Style.Triggers>
<EventTrigger RoutedEvent="Mouse.MouseDown">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" >
<EasingColorKeyFrame KeyTime="0:0:2" Value="White"/>
<!-- OriginalBackground is added at runtime -->
<EasingColorKeyFrame KeyTime="0:0:4" Value="{StaticResource OriginalBackground}"/> <!-- Load at runtime -->
</ColorAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Style.Triggers>
</Style>
</ResourceDictionary>

MainWindow.xaml

<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="BackgroundAnimationBlend.MainWindow"
x:Name="Window"
Title="MainWindow"
Width="640" Height="480"
Style="{DynamicResource WindowWithTrigger}"
Background="DarkBlue"> <!--Change background to whatever color you want -->
</Window>

MainWindow.xaml.cs

using System.IO;
using System.Text;
using System.Windows;
using System.Windows.Markup;

namespace BackgroundAnimationBlend
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
var rd2 = LoadFromFile();
this.Resources.MergedDictionaries.Add(rd2);
}

public ResourceDictionary LoadFromFile()
{
const string file = "Styles/StoryBoardResourceDictionary.xaml";

if (!File.Exists(file))
return null;

using (var fs = new StreamReader(file))
{
string xaml = string.Empty;
string line;
bool replaced = false;
while ((line = fs.ReadLine()) != null)
{
if (!replaced)
{
if (line.Contains("OriginalBackground"))
{
xaml += string.Format("<Color x:Key=\"OriginalBackground\">{0}</Color>", Background);
replaced = true;
continue;
}
}
xaml += line;
}
// Read in an EnhancedResourceDictionary File or preferably an GlobalizationResourceDictionary file
return XamlReader.Load(new MemoryStream(Encoding.UTF8.GetBytes(xaml))) as ResourceDictionary;
}
}
}
}

我现在不知道如何扩展它。所以也许这是一个疯狂的想法。但是在运行时加载样式并在加载之前将当前背景作为 xaml 字符串注入(inject)样式是我唯一可行的想法。

关于c# - 如何在不丢失原始颜色轨迹的情况下使背景颜色动画为新颜色并返回?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21467242/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com