2011-01-10 3 views
1

У меня есть две анимации, которые управляют цветом границы TextBox. Одна анимация изменяет цвет от желтого до голубого по умолчанию, а одна анимация меняет цвет на значение по умолчанию. Эти анимации начинаются с триггеров на IsFocused. Это прекрасно работает.WPF Конфликтующие анимации

Теперь я хочу, чтобы те же анимации запускались также с помощью IsMouseOver. Мое желаемое поведение заключается в том, что граница TextBox должна быть синей, если она имеет фокус, или если мышь нависает над ней, в противном случае она должна быть желтой. И должен быть анимированный переход между состояниями.

Как уже упоминалось, изменение цвета с помощью анимации, когда TextBox получает или теряет фокус, не является проблемой. Также нет проблем с изменением цвета, когда мышь перемещается по TextBox. Проблема состоит в том, чтобы ОБА. Тогда есть конфликт ...

Как я могу использовать обе эти анимации?

Вот код с обеих анимаций, но это НЕ работает, как я хочу, из-за конфликта. Что происходит, если я парить над TextBox раз анимации никогда не будет работать на IsFocused снова ...

<TextBox Width="200" Height="140" BorderBrush="Yellow" BorderThickness="4"> 
     <TextBox.Style> 
      <Style TargetType="TextBox"> 
       <Style.Resources> 
        <Storyboard x:Key="RecievedFocusOrMouseOverAnimation"> 
         <ColorAnimation 
          Storyboard.TargetProperty="BorderBrush.(SolidColorBrush.Color)" 
          To="Blue" 
          Duration="0:0:0.2" /> 
        </Storyboard> 
        <Storyboard x:Key="LostFocusOrMouseOutAnimation"> 
         <ColorAnimation 
          Storyboard.TargetProperty="BorderBrush.(SolidColorBrush.Color)" 
          To="Yellow" 
          Duration="0:0:0.2" /> 
        </Storyboard> 
       </Style.Resources> 
       <Style.Triggers> 
        <Trigger Property="IsFocused" Value="True"> 
         <Trigger.EnterActions> 
          <BeginStoryboard Name="IsFocusedTrueBeginStoryBoard" Storyboard="{StaticResource RecievedFocusOrMouseOverAnimation}" /> 
         </Trigger.EnterActions> 
         <Trigger.ExitActions> 
          <BeginStoryboard Name="IsFocusedFalseBeginStoryBoard" Storyboard="{StaticResource LostFocusOrMouseOutAnimation}" /> 
         </Trigger.ExitActions> 
        </Trigger> 
        <Trigger Property="IsMouseOver" Value="True"> 
         <Trigger.EnterActions> 
          <BeginStoryboard Name="IsMouseOverTrueBeginStoryboard" Storyboard="{StaticResource RecievedFocusOrMouseOverAnimation}" /> 
         </Trigger.EnterActions> 
         <Trigger.ExitActions> 
          <BeginStoryboard Name="IsMouseOverFalseBeginStoryboard" Storyboard="{StaticResource LostFocusOrMouseOutAnimation}" /> 
         </Trigger.ExitActions> 
        </Trigger> 
       </Style.Triggers> 
      </Style> 
     </TextBox.Style> 
    </TextBox> 

ответ

2

Я хотел бы предложить вам попробовать использовать MultiDataTrigger с условием ИЛИ как описанной here. Ваш код должен быть что-то вроде этого:

<MultiDataTrigger> 
    <MultiDataTrigger.Conditions> 
     <Condition Value="True"> 
      <Condition.Binding> 
       <MultiBinding Converter="{StaticResource BooleanOr}"> 
        <Binding Path="IsMouseOver" RelativeSource="{RelativeSource self}" /> 
        <Binding Path="IsFocused" RelativeSource="{RelativeSource self}" /> 
       </MultiBinding> 
      </Condition.Binding> 
     </Condition> 
    </MultiDataTrigger.Conditions> 
    <MultiDataTrigger.EnterActions> 
     <BeginStoryboard Name="IsFocusedTrueBeginStoryBoard" Storyboard="{StaticResource RecievedFocusOrMouseOverAnimation}" /> 
    </MultiDataTrigger.EnterActions> 
    <MultiDataTrigger.ExitActions> 
     <BeginStoryboard Name="IsFocusedFalseBeginStoryBoard" Storyboard="{StaticResource LostFocusOrMouseOutAnimation}" /> 
    </MultiDataTrigger.ExitActions> 
</MultiDataTrigger> 

BooleanOr является IMultiValueConverter, который вычисляет или между всеми его аргументами (вы можете найти его в коде, прикрепленной к статье в ссылке).

+0

Спасибо! Это отлично работает! :) – haagel

0

Кажется, что вам нужно остановить потенциальные раскопки, прежде чем вы начнете новый. Попробуйте это

<Trigger Property="IsFocused" Value="True"> 
    <Trigger.EnterActions> 
     <StopStoryboard BeginStoryboardName="IsMouseOverTrueBeginStoryboard"/> 
     <StopStoryboard BeginStoryboardName="IsMouseOverFalseBeginStoryboard"/> 
     <BeginStoryboard Name="IsFocusedTrueBeginStoryBoard" Storyboard="{StaticResource RecievedFocusOrMouseOverAnimation}" /> 
    </Trigger.EnterActions> 
    <Trigger.ExitActions> 
     <BeginStoryboard Name="IsFocusedFalseBeginStoryBoard" Storyboard="{StaticResource LostFocusOrMouseOutAnimation}" /> 
    </Trigger.ExitActions> 
</Trigger> 
<Trigger Property="IsMouseOver" Value="True"> 
    <Trigger.EnterActions> 
     <StopStoryboard BeginStoryboardName="IsFocusedTrueBeginStoryBoard"/> 
     <StopStoryboard BeginStoryboardName="IsFocusedFalseBeginStoryBoard"/> 
     <BeginStoryboard Name="IsMouseOverTrueBeginStoryboard" Storyboard="{StaticResource RecievedFocusOrMouseOverAnimation}" /> 
    </Trigger.EnterActions> 
    <Trigger.ExitActions> 
     <BeginStoryboard Name="IsMouseOverFalseBeginStoryboard" Storyboard="{StaticResource LostFocusOrMouseOutAnimation}" /> 
    </Trigger.ExitActions> 
</Trigger> 
+0

Спасибо за ответ, но я боюсь, что у решения есть недостатки. Например, попробуйте это: Удерживайте указатель мыши над TextBox - Граница станет синей. Перемещение фокуса в TextBox - Граница быстро становится желтой, а затем меняется на синюю (анимация запускается снова). Переместите указатель мыши из TextBox - Граница станет желтой, хотя TextBox все еще имеет фокус ... Спасибо, хотя, так как я узнал о StopStoryBoard. :) – haagel

+0

@haagel: Вы правы. Ничто не останавливает «IsMouseOverFalseBeginStoryboard» из-за того, что превращает желтый цвет «Border», и ничто не изменяет его на синий, так как эта IsFocused Storyboard уже запускает свою синюю анимацию :) –

Смежные вопросы