Я работаю над Windows Store App с C# и сталкивался с чем-то, где я не могу себе представить, что это сложно, но я не могу понять, как это сделать.XAML - простая анимация для простого пользовательского контроля
На моем MainPage.xaml
Я создал пользовательский элемент управления: A StackPanel
с горизонтальной ориентацией, всего лишь Image
и TextBlock
внутри. Как это:
<!-- language: lang-xml -->
<StackPanel Width="300" Height="100" Orientation="Horizontal" Margin="0,0,0,20" Tapped="LoremIpsum_Tapped">
<Image Source="/Assets/pic.jpg" Margin="20"/>
<TextBlock FontFamily="Segoe UI" FontSize="30" VerticalAlignment="Center">
Lorem Ipsum
</TextBlock>
</StackPanel>
который выглядит следующим образом:
Я использую его в качестве пользовательского типа кнопки, чтобы добраться до какой-то суб-страницы. Теперь дело в том, что есть нет анимаций. Я хотел иметь типичную анимацию, которую ListItem
имеет в SplitView: при нажатии она сокращается, возвращается в нормальное состояние, когда отпущена или когда указатель выходит из виртуальных границ элемента управления. Я не смог найти объявление/определение анимации, связанное с этими ListItems (Common. StandardStyles.xaml
Standard130ItemTemplate
). Но я узнал (here), что для этого есть предопределенные анимации: PointerDownThemeAnimation
и PointerUpThemeAnimation
. Но потом мне потребовалось немало времени, чтобы узнать, как применять их к контролю. Вы можете подумать, что образец, упомянутый на this site specifically about those pointer theme animations (около C#), должен помочь, но это приводит к sample for HTML/Javascript animations. Но я нашел решения here, here и here.
Так что мне нужно было Storyboard
s в ресурсах управления, имя, чтобы элемент управления мог быть нацелен и обработчики событий в коде.
Наносится на моем XAML становится это:
<!-- language: lang-xml -->
<StackPanel x:Name="LoremIpsum" Width="300" Height="100" Orientation="Horizontal" Margin="0,0,0,20" Tapped="LoremIpsum_Tapped" PointerPressed="LoremIpsum_AnimDown" PointerReleased="LoremIpsum_AnimUp" PointerExited="LoremIpsum_AnimUp">
<Image Source="/Assets/pic.jpg" Margin="20"/>
<TextBlock FontFamily="Segoe UI" FontSize="30" VerticalAlignment="Center">
Lorem Ipsum
</TextBlock>
<StackPanel.Resources>
<Storyboard x:Name="pointerDownStoryboard">
<PointerDownThemeAnimation TargetName="LoremIpsum" />
</Storyboard>
<Storyboard x:Name="pointerUpStoryboard">
<PointerUpThemeAnimation TargetName="LoremIpsum" />
</Storyboard>
</StackPanel.Resources>
</StackPanel>
плюс дополнительные обработчики событий в отделенном коде:
<!-- language: lang-cs -->
private void Latest_AnimDown(object sender, PointerRoutedEventArgs e)
{
pointerDownStoryboard.Begin();
}
private void Latest_AnimUp(object sender, PointerRoutedEventArgs e)
{
pointerUpStoryboard.Begin();
}
Это работало. Но ... поскольку у меня много таких пользовательских элементов управления, я, конечно, не хочу добавлять все это для каждого элемента управления. Как упоминалось ранее, Standard130ItemTemplate
не помогло. Поэтому я подумал о пользовательских элементах управления. Я надеялся, что могу просто определить MyStackPanel
, это ничего, кроме StackPanel
+ StoryBoard
s, и что нацеливание на x: Name будет работать, и, возможно, я могу поместить обработчики событий в код LayoutAwarePage, так что все остальные наследуют от Это.
Я начал искать, как это сделать, и нашел этот образец того, как создавать пользовательские элементы управления: XAML user and custom controls sample.
Там в пользовательский элемент управления в Generic.xml:
<!-- language: lang-xml -->
xmlns:local="using:UserAndCustomControls">
<Style TargetType="local:BasicCustomControl">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:BasicCustomControl">
<Border
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
И файл кода, но не код-за:
<!-- language: lang-cs -->
namespace UserAndCustomControls
{
public sealed class BasicCustomControl : Control
{
public BasicCustomControl()
{
this.DefaultStyleKey = typeof(BasicCustomControl);
}
}
}
Но образец не содержал ничего об анимации. Поэтому я играл с примером, пытаясь добавить StoryBoard
s к границе или к ControlTemplate, добавив обработчики событий к самостоятельно созданному коду Generic.xaml.cs. Ничего не получилось.
Затем я нашел this, но не был уверен, как и почему поставить обработчик событий в класс BasicCustomControl
. Я попробовал это в любом случае:
Generic.xaml
В:
<!-- language: lang-xml -->
xmlns:local="using:UserAndCustomControls">
<Style TargetType="local:BasicCustomControl">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:BasicCustomControl">
<Border x:Name="Border"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<Border.Resources>
<Storyboard x:Name="pointerDownStoryboard">
<PointerDownThemeAnimation TargetName="Border" />
</Storyboard>
<Storyboard x:Name="pointerUpStoryboard">
<PointerUpThemeAnimation TargetName="Border" />
</Storyboard>
</Border.Resources>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
И в BasicCustomControl.cs
:
<!-- language: lang-cs -->
protected override void OnPointerPressed(PointerRoutedEventArgs e)
{
((Storyboard)this.Resources["PointerDownThemeAnimation"]).Begin(this);
}
Это не сработало. Метод Begin()
не принимает аргументов и без аргумента, с которым была выполнена сборка, но при нажатии на элемент управления я получил сообщение System.Runtime.InteropServices.COME.
Тогда я нашел это на SO: How to add XAML storyboard animation to a full blown WPF Custom Control in an XBAP?
Это кажется интересным решением, но я не понимаю. Вот также описание VisualState для пользовательских элементов управления, но опять же я не знаю, как применить это к моим потребностям: Quickstart: control templates
Теперь на этом этапе я потратил довольно много времени на это, и я просто думаю, что для это Простая вещь - простая, даже предопределенная анимация для настраиваемого элемента управления -, должно быть простое решение. Надеюсь, я просто что-то пропустил, и на самом деле это не так сложно.
Резюмируя вопросы:
- Где анимация в
Standard130ItemTemplate
определены и «прикрепленные» к шаблону? - Есть ли элемент управления, который я могу «наследовать» от того, что ведет себя так, как я хочу (только эти анимации вверх/вниз на трех событиях)?
- Есть ли способ создать такой контроль, который я могу унаследовать от - с помощью кода XAML +?
- Есть ли способ сделать это только с помощью XAML? Это предпочтительнее прежнего?
- Есть ли простой пример или учебник по этому вопросу?
- Есть ли коллекции пользовательских элементов управления, которые я могу загрузить и использовать? Я не смог найти никого.