我正在学习如何使用VisualStates,并遇到这个问题:
我有一个Control模板,里面有Grid,网格包含图像和两个TextBlocks。我希望每当鼠标放在一个控件上时放置一个矩形。互联网上的大多数例子都使用了Blend,我目前还没有这个例子,而且我也想学习如何手动完成。这是一个简单的模板(我使用了常量颜色使其更简单):
<ControlTemplate x:Key="MyControlTemplate" TargetType="SomeControl">
<Grid Cursor="Hand" Width="Auto">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Image Grid.RowSpan="2" HorizontalAlignment="Left" VerticalAlignment="Top" Stretch="None" Source="{Binding ImageUrl}" />
<TextBlock x:Name="TitleElement" Grid.Column="1" Margin="4" TextWrapping="Wrap" HorizontalAlignment="Left" VerticalAlignment="Top" Text="{Binding Content}" Foreground="{StaticRecource TitleForegroundBrush}" />
<TextBlock x:Name="DescriptionElement" Grid.Row="1" Grid.Column="1" Margin="4,0,4,4" MaxWidth="200" TextWrapping="Wrap" HorizontalAlignment="Left" VerticalAlignment="Top" Text="{Binding Description}" Foreground="{StaticResource DescriptionElementForeground}" />
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Unfocused"/>
<VisualState x:Name="Focused">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="TitleElement" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="00:00:00" Value="{StaticResource TitleElementFocusedForeground}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Grid>
</ControlTemplate>
鼠标悬停时更改TitleElement的前景正在运行。现在我想在鼠标悬停上完全控制边框(不仅仅是它的一部分)。我尝试的第一件事是将Border作为网格容器并将StoryBoard放在VisualStateGroup中:
<Border x:Name="ControlBorder" BorderBrush="{StaticResource ControlBorderBrush}" BorderThickness="0">
<Grid Cursor="Hand" Width="Auto">
....
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Unfocused"/>
<VisualState x:Name="Focused">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="TitleElement" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="00:00:00" Value="{StaticResource TitleElementFocusedForeground}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ControlBorder" Storyboard.TargetProperty="BorderThickness">
<DiscreteObjectKeyFrame KeyTime="00:00:00" Value="1" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
这不起作用,事实上,现在TitleElement甚至没有像过去那样改变前景色。但是,在网格中添加Border作为第4个元素(RowSpan和ColumnSpan设置为整个网格)可以工作!但是有一些副作用我不喜欢,例如,当我移动鼠标时矩形是“闪烁”控制。问题:
感谢。
答案 0 :(得分:2)
需要在控件模板的根元素上管理视觉状态,如果在根周围放置一个元素,它们将被忽略,您需要将它们移动。< / p>
在控件的styles and templates页面上列出了特定的状态,所有普通状态应该是相同的(因为它们是“常见的”),所支持的状态也列在控件的页面。 (例如Button
有Normal
,Pressed
,MouseOver
和Disabled
)
适用于整个模板(参见1.)