Применение визуального состояния к элементу Border - PullRequest
1 голос
/ 28 февраля 2012

Я учусь работать с VisualStates, и у меня возникла эта проблема:

У меня есть шаблон Control, в котором есть Grid, а 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 установлены на всю сетку) работает !, но есть некоторые побочные эффекты, которые мне не нравятся, например, прямоугольник «мигает», когда я перемещаю мышь над контроль. Вопросы:

  1. Почему размещение Grid внутри Rectangle не работает, а Rectangle внутри Grid работает?
  2. Я вижу, что существует VisualGroup CommonStates, который должен быть где-то предопределен. Как мы узнаем, какие из них предопределены, и их соответствующие имена?
  3. Какова область применения VisualStateManager? Если я определю его внутри элемента, относится ли он только к этому элементу или ко всему ControlTemplate?

Спасибо.

1 Ответ

2 голосов
/ 28 февраля 2012
  1. Необходимо управлять визуальными состояниями в корневом элементе шаблона элемента управления. Если вы поместите элемент вокруг своего корня, он будет игнорироваться, вам нужно будет переместить его вверх..

  2. На странице стилей и шаблонов элементов управления перечислены конкретные состояния, общие состояния должны быть одинаковыми для всех (так как они являются "общими")те, которые поддерживаются, также перечислены на страницах для элементов управления.(например, Button имеет Normal, Pressed, MouseOver и Disabled)

  3. Относится ко всему шаблону (см. 1.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...