我如何从外部模板控制模板内的元素
我很难找到这个问题的解决方案。我有一个控件模板,其中有一个内容演示者和一个自定义视觉状态管理器,在 SelectionStates 组下具有“选定”和“未选定”视觉状态。在内容演示者的内容模板内,我有一个椭圆,我想根据视觉状态为其 Fill 属性设置动画。这不可能直接实现,因为椭圆位于内容演示者的内容模板内。是否有任何间接的解决方法可以做到同样的事情。以下是我的模板,
<Style TargetType="local:TabNavigationItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:TabNavigationItem">
<Grid>
<vsm:VisualStateManager.VisualStateGroups>
<vsm:VisualStateGroup x:Name="SelectionStates">
<vsm:VisualState x:Name="Selected">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="TabStripEllipse"
Storyboard.TargetProperty="Background">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<SolidColorBrush Color="#FF3B5A82"/>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</vsm:VisualState>
<vsm:VisualState x:Name="UnSelected">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="TabStripEllipse"
Storyboard.TargetProperty="Background">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<SolidColorBrush Color="Transparent"/>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</vsm:VisualState>
</vsm:VisualStateGroup>
</vsm:VisualStateManager.VisualStateGroups>
<ContentPresenter>
<ContentPresenter.ContentTemplate>
<DataTemplate x:Key="tabNavigationItemTemplate">
<Border Padding="1">
<Ellipse x:Name="TabStripEllipse"
Fill="Transparent"
Stroke="#FF3B5A82" Cursor="Hand"
Height="8" Width="8"/>
</Border>
</DataTemplate>
</ContentPresenter.ContentTemplate>
</ContentPresenter>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
感谢您的想法和建议。
您可能还想将我的 xaml 文件如下所示。但是与外部模板的目标类型相关的属性应该可以通过内部数据模板访问。
<Style TargetType="local:TabNavigationItem">
<Setter Property="ItemContentTemplate" Value="{StaticResource contentTemplate}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:TabNavigationItem">
<Grid>
<Border>
<ContentPresenter>
<ContentPresenter.ContentTemplate>
<vsm:VisualStateManager.VisualStateGroups>
<vsm:VisualStateGroup x:Name="SelectionStates">
<vsm:VisualState x:Name="Selected">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="TabItemPresenter"
Storyboard.TargetProperty="Background">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<SolidColorBrush Color="#FF3B5A82"/>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</vsm:VisualState>
<vsm:VisualState x:Name="UnSelected">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="TabItemPresenter"
Storyboard.TargetProperty="Background">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<SolidColorBrush Color="Transparent"/>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</vsm:VisualState>
</vsm:VisualStateGroup>
</vsm:VisualStateManager.VisualStateGroups>
<Border Padding="1">
<Ellipse x:Name="TabStripEllipse"
Fill="Transparent"
Stroke="#FF3B5A82" Cursor="Hand"
Height="8" Width="8"/>
</Border>
</ContentPresenter.ContentTemplate>
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Am facing hard time finding solution for this problem. I've a control template in which i've a content presenter and a Custom visual state manager with visual state Selected and UnSelected under SelectionStates group. Inside the content presenter's content template i've an ellipse whose Fill property i want to animate according to the visual state. This is not directly possible since the ellipse is residing inside the content presenter's content template. Is ther any indirect workaround possible to do the same. Below is my template
<Style TargetType="local:TabNavigationItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:TabNavigationItem">
<Grid>
<vsm:VisualStateManager.VisualStateGroups>
<vsm:VisualStateGroup x:Name="SelectionStates">
<vsm:VisualState x:Name="Selected">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="TabStripEllipse"
Storyboard.TargetProperty="Background">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<SolidColorBrush Color="#FF3B5A82"/>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</vsm:VisualState>
<vsm:VisualState x:Name="UnSelected">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="TabStripEllipse"
Storyboard.TargetProperty="Background">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<SolidColorBrush Color="Transparent"/>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</vsm:VisualState>
</vsm:VisualStateGroup>
</vsm:VisualStateManager.VisualStateGroups>
<ContentPresenter>
<ContentPresenter.ContentTemplate>
<DataTemplate x:Key="tabNavigationItemTemplate">
<Border Padding="1">
<Ellipse x:Name="TabStripEllipse"
Fill="Transparent"
Stroke="#FF3B5A82" Cursor="Hand"
Height="8" Width="8"/>
</Border>
</DataTemplate>
</ContentPresenter.ContentTemplate>
</ContentPresenter>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Your thoughts and suggestions are appreciated..
you may also want to put my xaml file as below.. but the properties related to target type of outer template should be accessible by inner data template.
<Style TargetType="local:TabNavigationItem">
<Setter Property="ItemContentTemplate" Value="{StaticResource contentTemplate}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:TabNavigationItem">
<Grid>
<Border>
<ContentPresenter>
<ContentPresenter.ContentTemplate>
<vsm:VisualStateManager.VisualStateGroups>
<vsm:VisualStateGroup x:Name="SelectionStates">
<vsm:VisualState x:Name="Selected">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="TabItemPresenter"
Storyboard.TargetProperty="Background">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<SolidColorBrush Color="#FF3B5A82"/>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</vsm:VisualState>
<vsm:VisualState x:Name="UnSelected">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="TabItemPresenter"
Storyboard.TargetProperty="Background">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<SolidColorBrush Color="Transparent"/>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</vsm:VisualState>
</vsm:VisualStateGroup>
</vsm:VisualStateManager.VisualStateGroups>
<Border Padding="1">
<Ellipse x:Name="TabStripEllipse"
Fill="Transparent"
Stroke="#FF3B5A82" Cursor="Hand"
Height="8" Width="8"/>
</Border>
</ContentPresenter.ContentTemplate>
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
也许您有以这种方式使用 ContentPresenter 的原因。内容呈现器的正常使用将充当绑定到控件属性的内容的占位符。您通常不会使用 ContentPresenter,然后向其提供您自己的 DataTemplate。这是我的 Xaml 版本,没有明显不必要的内容演示器:-
现在您的 VSM 应该能够找到椭圆。
Perhaps you have a reason why you are using a ContentPresenter in this way. The normal use of a content presenter would be act as a place holder for content being bound to a property of the control. You wouldn't normally use ContentPresenter and then provide your own DataTemplate to it. Here is my version of your Xaml without the apparrently unnecessary content presenter:-
Now your VSM should be able to find the Ellipse.