#c# #uwp
#c# #uwp
Вопрос:
У меня есть этот код. Это всего лишь пример. Я хочу сделать это с помощью кода. Как анимировать свойство переднего плана нескольких элементов «Run» в текстовом блоке?
<Page
x:Class="AnimationTest.MainPage"
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:local="using:AnimationTest"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
mc:Ignorable="d">
<Grid>
<TextBlock
x:Name="_textBlockElement"
HorizontalAlignment="Center"
VerticalAlignment="Center"
FontSize="72"><Run x:Name="_run1" Text="Hel" /><Run Text="lo" />
<TextBlock.Triggers>
<EventTrigger>
<BeginStoryboard>
<Storyboard x:Name="ColorStoryboard">
<ColorAnimation
AutoReverse="True"
RepeatBehavior="Forever"
Storyboard.TargetName="_textBlockElement"
Storyboard.TargetProperty="(TextBlock.Foreground).(SolidColorBrush.Color)"
To="Red"
Duration="0:0:2" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</TextBlock.Triggers>
</TextBlock>
</Grid>
</Page>
Комментарии:
1. Во время тестирования
<Run x:Name="_run1" Text="Hel" /><Run Text="lo" />
можно было бы добавить анимацию одновременно. Не могли бы вы рассказать, какую функцию вы хотите реализовать?2. @NicoZhu-MSFT, есть текстовый блок, который состоит из нескольких элементов «Run». Каждый элемент окрашен в свой собственный цвет. Мне нужно, чтобы все элементы Run становились красными при наведении курсора мыши на текстовый блок. Когда курсор мыши удаляется от текстового блока, все элементы Run возвращаются к своим предыдущим цветам. Я сделаю это из кода. Код XAML — это просто пример.
Ответ №1:
Оке, так что это заняло довольно много времени, но оказалось вполне выполнимым.
Ключ в том, чтобы создать две раскадровки в коде с правильной анимацией, а затем добавить эти раскадровки к ресурсам любого Run
родительского элемента.
Давайте начнем с XAML
кода, который довольно прост:
<Grid>
<TextBlock x:Name="TestBlock"
HorizontalAlignment="Center" VerticalAlignment="Center"
PointerEntered="TestBlock_PointerEntered"
PointerExited="TestBlock_PointerExited">
<Run x:Name="Run1" Text="Test1" Foreground="Blue"/>
<Run x:Name="Run2" Text="Test2" Foreground="Green"/>
<!-- ... -->
</TextBlock>
</Grid>
Для простоты я уже определил имена и передние планы Run
‘s.
Теперь нам нужно определить раскадровки и анимации в коде.
Я решил сделать это в конструкторе (после InitializeComponent()
!). Теоретически вы должны иметь возможность также вставить этот код в Page_Loaded
событие.
public MainPage()
{
InitializeComponent();
SetupStoryBoards();
}
void SetupStoryBoards()
{
// Define duration and storyboards to red and original color
var duration = new Duration(TimeSpan.FromSeconds(1));
var toRedStory = new Storyboard { Duration = duration };
// completed events can be subscribed to, to register when animation is done
//toRedStory.Completed = Story_Completed;
var toOriginalStory = new Storyboard { Duration = duration };
//toOriginalStory.Completed = ToOriginalStory_Completed;
foreach (Run r in TestBlock.Inlines)
{
// Filter out any inlines that are not a named Run
if (string.IsNullOrEmpty(r.Name))
continue;
// Define the animations
var toRedAnim = new ColorAnimation
{
Duration = duration,
To = Colors.Red,
EnableDependentAnimation = true
};
var toOriginalAnim = new ColorAnimation
{
Duration = duration,
To = (r.Foreground as SolidColorBrush).Color, // Causes animation to go back to original foreground color of Run
EnableDependentAnimation = true
};
// Add animations to the storyboards and associate animations with the Run
toRedStory.Children.Add(toRedAnim);
toOriginalStory.Children.Add(toOriginalAnim);
Storyboard.SetTargetName(toRedAnim, r.Name);
Storyboard.SetTargetName(toOriginalAnim, r.Name);
Storyboard.SetTargetProperty(toRedAnim, "(Run.Foreground).(SolidColorBrush.Color)");
Storyboard.SetTargetProperty(toOriginalAnim, "(Run.Foreground).(SolidColorBrush.Color)");
}
// Add the storyboards to the resources of any parent of the Run's for easy retrieval later and to make the animations find the Run's
// I choose the resources of the textblock that contains the Run's
TestBlock.Resources.Add("toRedStory", toRedStory);
TestBlock.Resources.Add("toOriginalStory", toOriginalStory);
}
Теперь, чтобы выполнить анимацию, мы добавляем PointerEntered
обработчики PointerExited
событий и и запускаем там правильные раскадровки:
private void TextBlock_PointerEntered(object sender, PointerRoutedEventArgs e)
{
var story = TestBlock.Resources["toRedStory"] as Storyboard;
story.Begin();
}
private void TextBlock_PointerExited(object sender, PointerRoutedEventArgs e)
{
var story = TestBlock.Resources["toOriginalStory"] as Storyboard;
story.Begin();
}
Вы должны иметь возможность расширять это везде, где это необходимо, однако я обнаружил, что для этого
EnableDependentAnimation
должно быть установленоtrue
значение, поскольку в противном случае оно не будет работать.