phl*_*low 5 c# xaml windows-store-apps
我正在使用C#开发一个Windows应用商店应用程序并遇到了一些我无法想象它很困难的事情,但我无法找到如何做到这一点.
在我的MainPage.xaml我创建了一个用户控制: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>
Run Code Online (Sandbox Code Playgroud)
看起来像这样:

我将它用作自定义类型的按钮来访问某个子页面.现在的问题是,没有动画.我希望拥有ListItemSplitView中的典型动画:按下时缩小,释放时或指针退出控件的虚拟边框时恢复正常.我找不到与那些ListItems相关的动画声明/定义(Common.StandardStyles.xaml Standard130ItemTemplate).但我发现(这里)有预定义的动画:PointerDownThemeAnimation和PointerUpThemeAnimation.但是后来我花了很长时间才找到如何将它们应用到控件中.您可能认为本网站上提到的示例专门针对那些指针主题动画(关于C#)应该有所帮助,但它会导致HTML/Javascript动画的示例.但我在这里,这里和这里找到了解决方案.
所以我需要Storyboard在控件资源中使用一个名称,这样控件就可以在代码隐藏中成为目标和事件处理程序.
在我的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>
Run Code Online (Sandbox Code Playgroud)
加上代码隐藏中的其他事件处理程序:
<!-- language: lang-cs -->
private void Latest_AnimDown(object sender, PointerRoutedEventArgs e)
{
pointerDownStoryboard.Begin();
}
private void Latest_AnimUp(object sender, PointerRoutedEventArgs e)
{
pointerUpStoryboard.Begin();
}
Run Code Online (Sandbox Code Playgroud)
这很有效.但是......由于我有很多这样的用户控件,我当然不希望为每个控件添加所有这些.如前所述,Standard130ItemTemplate没有帮助.所以我想到了自定义控件.我希望我可以只定义一个MyStackPanel只有a StackPanel+ StoryBoards的内容,并且x:Name的定位可以工作,也许我可以将事件处理程序放在LayoutAwarePage代码隐藏中,所以其他人都继承它.
我开始寻找如何做到这一点,并找到了如何创建自定义控件的示例:XAML用户和自定义控件示例.
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>
Run Code Online (Sandbox Code Playgroud)
和代码文件,但不是代码隐藏:
<!-- language: lang-cs -->
namespace UserAndCustomControls
{
public sealed class BasicCustomControl : Control
{
public BasicCustomControl()
{
this.DefaultStyleKey = typeof(BasicCustomControl);
}
}
}
Run Code Online (Sandbox Code Playgroud)
但样本中没有任何关于动画的内容.所以我玩了一下这个例子,尝试将StoryBoards 添加到Border或ControlTemplate,将事件处理程序添加到自己创建的Generic.xaml.cs代码隐藏中.没有任何效果.
然后我发现了这个,但不确定如何以及为什么将事件处理程序放入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>
Run Code Online (Sandbox Code Playgroud)
并在BasicCustomControl.cs:
<!-- language: lang-cs -->
protected override void OnPointerPressed(PointerRoutedEventArgs e)
{
((Storyboard)this.Resources["PointerDownThemeAnimation"]).Begin(this);
}
Run Code Online (Sandbox Code Playgroud)
那没用.该Begin()方法不接受参数,如果没有参数,则构建成功,但单击控件时出现System.Runtime.InteropServices.COMException.
然后我在SO上找到了这个:如何在XBAP中将XAML故事板动画添加到完整的WPF自定义控件中?
这似乎是一个有趣的解决方案,但我不明白.这里还有一些用于自定义控件的VisualState内容的描述,但我不知道如何将其应用于我的需求:快速入门:控制模板
现在,在这一点上,我花了相当多的时间在这上面,我只是想到这个简单的事情 - 一个简单的,甚至预定义的自定义控件动画 - 必须有一个简单的解决方案.我希望我只是忽略了一些事情并不是那么复杂.
总结一下问题:
Standard130ItemTemplate定义的动画和模板的"附加"在哪里?创建自定义样式。在此示例中,我将图像源绑定到内容字段。所以我只需要把我的图像路径放在该字段中(例如“Assets/Image.png”)。如果像这样添加自定义动画第一次更容易理解,那就太好了。
<Style x:Key="ImageButtonStyle" TargetType="ButtonBase">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ButtonBase">
<Grid x:Name="RootGrid" Background="Transparent">
<Image x:Name="ImageLabel" Source="{TemplateBinding Content}"/>
<Rectangle
x:Name="FocusVisualWhite"
IsHitTestVisible="False"
Stroke="{StaticResource FocusVisualWhiteStrokeThemeBrush}"
StrokeEndLineCap="Square"
StrokeDashArray="1,1"
Opacity="0"
StrokeDashOffset="1.5"/>
<Rectangle
x:Name="FocusVisualBlack"
IsHitTestVisible="False"
Stroke="{StaticResource FocusVisualBlackStrokeThemeBrush}"
StrokeEndLineCap="Square"
StrokeDashArray="1,1"
Opacity="0"
StrokeDashOffset="0.5"/>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="PointerOver">
</VisualState>
<VisualState x:Name="Pressed">
<Storyboard>
<PointerDownThemeAnimation TargetName="ImageLabel" />
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled">
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="FocusStates">
<VisualState x:Name="Focused">
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="FocusVisualWhite"
Storyboard.TargetProperty="Opacity"
To="1"
Duration="0"/>
<DoubleAnimation
Storyboard.TargetName="FocusVisualBlack"
Storyboard.TargetProperty="Opacity"
To="1"
Duration="0"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Unfocused" />
<VisualState x:Name="PointerFocused" />
</VisualStateGroup>
<VisualStateGroup x:Name="CheckStates">
<VisualState x:Name="Checked">
<Storyboard>
<DoubleAnimation Duration="0" To="0" Storyboard.TargetName="OutlineGlyph" Storyboard.TargetProperty="Opacity"/>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="BackgroundGlyph" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource AppBarItemForegroundThemeBrush}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="BackgroundCheckedGlyph" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0" Value="Visible"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Content" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource AppBarItemPressedForegroundThemeBrush}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Unchecked"/>
<VisualState x:Name="Indeterminate"/>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2872 次 |
| 最近记录: |