我需要创建几个代表不同点对象的样式,它们都做同样的事情。更具体地说,它是一堆ESRI MarkerSymbols,可以是Circle,Square,Star等,但这可能与特定问题无关。
当用户悬停或点击它们时,每个点的行为都会完全相同 - 这是通过视觉状态组完成的(我删除了几个动画以节省空间:
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="SelectionStates">
<VisualState x:Name="Unselected" />
<VisualState x:Name="Selected">
<Storyboard Storyboard.TargetName="shapeElement">
<DoubleAnimation BeginTime="0:0:0" Duration="0:0:0.5"
Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleX)"
To="1" />
<DoubleAnimation BeginTime="0:0:0" Duration="0:0:0.5"
Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleY)"
To="1" />
...................................................................
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal">
<Storyboard Storyboard.TargetName="shapeElement2">
<DoubleAnimation BeginTime="0:0:0" Duration="0:0:0.1"
Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleX)"
To="1" />
<DoubleAnimation BeginTime="0:0:0" Duration="0:0:0.1"
Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleY)"
To="1" />
<ObjectAnimationUsingKeyFrames BeginTime="0:0:0.1" Duration="0:0:0"
Storyboard.TargetProperty="(UIElement.Visibility)">
<DiscreteObjectKeyFrame KeyTime="0:0:0">
<DiscreteObjectKeyFrame.Value>
<Visibility>Collapsed</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="MouseOver">
<Storyboard Storyboard.TargetName="shapeElement2">
<ObjectAnimationUsingKeyFrames BeginTime="00:00:00" Duration="0:0:0.01"
Storyboard.TargetProperty="(UIElement.Visibility)">
<DiscreteObjectKeyFrame KeyTime="00:00:00">
<DiscreteObjectKeyFrame.Value>
<Visibility>Visible</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
<DoubleAnimation BeginTime="00:00:00" Duration="0:0:0.1"
Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleX)"
To="1.75" />
<DoubleAnimation BeginTime="00:00:00" Duration="0:0:0.1"
Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleY)"
To="1.75" />
...................................................................
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
由于我想要创建几个所有将使用此Visual Group Groups集合的形状,如何将其转换为资源?换句话说,我该怎么做:
<esri:MarkerSymbol x:Key="CircleLocationPointMarker" OffsetX="6" OffsetY="6" >
<esri:MarkerSymbol.ControlTemplate>
<ControlTemplate>
<Grid >
<Ellipse x:Name="shapeElement">
..............................................
</Ellipse>
<Ellipse x:Name="shapeElement2">
..............................................
</Ellipse>
<Border x:Name="LocationLabel">
..............................................
</Border>
<VisualStateManager.VisualStateGroups>
---HOW DO I USE A RESOURCE OR SEVERAL RESOURCES??---
</VisualStateManager.VisualStateGroups>
</Grid>
</ControlTemplate>
</esri:MarkerSymbol.ControlTemplate>
</esri:MarkerSymbol>
并为Square和Star说另一个,依此类推。希望这是有道理的。
答案 0 :(得分:1)
好的,我可以想到两种可能的解决方案:
数字1:
从MarkerSymbol
派生并添加公共 Shape 属性(或者更好地使用Path),现在您只需开发一个ControlTemplate
VisualStates
使用新添加的属性。无论您想在何处使用特殊标记,您都可以提供自定义的形状/几何图形,或者您可以从中进一步派生它以创建默认的形状标记:
<ControlTemplate TargetType="ShapedMarker" x:Key="ShapedMarkerDefaultTemplate">
<Grid>
<VisualStateManager.VisualStateGroups>...</...>
<Path x:Name="shapeElement" Data="{TemplateBinding ShapeGeometry}"/>
<Path x:Name="shapeElement2" Data="{TemplateBinding ShapeGeometry}"/>
<Border x:Name="LocationLabel"/>
</Grid>
</ControlTemplate>
<Style TargetType="ShapedMarker">
<Setter Property="Template"
Value="{StaticResource ShapedMarkerDefaultTemplate}"/>
</Style>
和代码
public class ShapedMarker : MarkerSymbol
{
public Geometry ShapeGeometry { get {...} set {...} }
...DependencyProperty ... "ShapeGeometry" ...
public ShapedMarker(){ DefaultStyleKey = typeof(ShapedMarker); }
}
public class CircleLocationPointMarker : ShapedMarker
{
public CircleLocationPointMarker(){this.ShapeGeometry = new EllipseGeometry();}
}
数字2:
基本上我所描述的here。您可以编写自己的实用程序类来以编程方式生成VisualStates
和所有关联的Animations
,这样可以避免一遍又一遍地编写相同的标记。它是一种经过尝试和信任的方法,没有性能影响,动画只创建一次。然而,这种方法并不常见,很多开发人员都不愿意尝试任何不寻常的事情(我甚至在我自己的团队中做过观察)。
标记可能如下所示:
<ControlTemplate ...>
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"
utils:AddAnimations.ScaledAndCollapsed="shapeElement2"/>
<VisualState x:Name="MouseOver"
utils:AddAnimations.ScaledAndVisible="shapeElement2"/>
<.../>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
...
</Grid>
</ControlTemplate>
您甚至可以混合使用xaml声明的动画和通过实用程序方法添加的动画。该代码将尊重任何现有的动画。