【问题标题】:Declare a VisualStateManager Group Collection as a Resource in a Control Template将 VisualStateManager 组集合声明为控件模板中的资源
【发布时间】:2014-06-14 17:08:27
【问题描述】:

我需要创建几种样式来代表不同的点对象,它们都做同样的事情。更具体地说,它是一堆 ESRI MarkerSymbol,可以是圆形、方形、星形等,但可能与特定问题无关。

当用户悬停或单击它们时,每个点的行为方式完全相同 - 这是通过 Visual State Groups 完成的(我删除了几个动画以节省空间:

<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>

由于我想创建几个都将使用此视觉状态组集合的形状,我如何将其转换为资源?换句话说,我该怎么做:

<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>

然后说一个方形和一个星形,以此类推。希望这是有道理的。

【问题讨论】:

标签: visual-studio silverlight xaml controltemplate arcobjects


【解决方案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 中声明的动画和通过实用程序方法添加的动画。该代码将尊重任何现有的动画。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多