【问题标题】:WPF Event Trigger Change Other UI elementWPF 事件触发器更改其他 UI 元素
【发布时间】:2014-09-28 09:09:59
【问题描述】:

我在使用ItemTemplate 的XAML 中定义了ListBox。 在ItemTemplate 里面放了Image。

<ListBox.ItemTemplate>
<ListBox.ItemsPanel>
 <ItemsPanelTemplate>
  <WrapPanel x:Name="itmTempPanel" IsItemsHost="True" ItemWidth="60" ItemHeight="60" Width="{Binding ElementName=lstFilesDropped, Path=Width}"/>
 </ItemsPanelTemplate>
</ListBox.ItemsPanel>
...
<Image>
 <Image.Triggers>
  <EventTrigger RoutedEvent="MouseEnter">
   <BeginStoryboard>
    <Storyboard>
     <DoubleAnimation Storyboard.TargetProperty="Height" To="71" Duration="0:0:0.3" />
     <DoubleAnimation Storyboard.TargetName="itmTempPanel" Storyboard.TargetProperty="Height" To="71"      Duration="0:0:0.3" />
    </Storyboard>
   </BeginStoryboard>
  </EventTrigger>
 </Image.Triggers>
</Image>
</ListBox.ItemTemplate>

当鼠标进入图像时,我想在该图像高度在我在ItemsPanelTemplate 中定义的WrapPanel 上开始故事板。

当鼠标进入此图像时,出现以下异常: “在‘​​System.Windows.Controls.Image’的名称范围内找不到‘itmTempPanel’名称。”

如何更改故事板开头的元素的其他元素属性。

感谢您的帮助!!

【问题讨论】:

    标签: c# wpf xaml triggers event-triggers


    【解决方案1】:

    有两种方法可以解决这个问题。第一个是使用{x:Reference} .NET 4.0 中用于 WPF 的功能。如果您的应用程序面向 .NET 4.0,您应该遵循这种方法。想法是将Storyboard.Target 设置为您要设置动画的对象(在本例中为WrapPanel)。虽然我们可以将Binding 用于Storyboard.Target,但我们不能使用RelativeSourceElementName 设置绑定源,因为Storyboard(或Timeline)不是FrameworkElement(或FrameworkContentElement)。指定源的唯一方法是设置Source 属性。但是,我们通常可以将其设置为 StaticResourceDynamicResource 或直接(使用元素语法)。幸运的是 {x:Reference} 是在 .NET 4.0 中引入的,这可以帮助您引用 XAML 中的任何命名对象(它的工作方式与 ElementName 不同)。这是第一种方法的代码:

    <DoubleAnimation Storyboard.Target="{Binding Source={x:Reference itmTempPanel}}" 
                     Storyboard.TargetProperty="Height" 
                     To="71" Duration="0:0:0.3" />    
    

    第二种方法基于DataTrigger。但是,此触发器不适用于Image,它完全适用于WrapPanel。但现在ElementName 可用于将触发源绑定到Image。所以这种方式在{x:Reference}不支持的情况下是可以使用的。

    <WrapPanel x:Name="itmTempPanel" IsItemsHost="True" ItemWidth="60" ItemHeight="60" 
               Width="{Binding ElementName=lstFilesDropped, Path=Width}">
      <WrapPanel.Style>
         <Style TargetType="WrapPanel">
            <Style.Triggers>
               <DataTrigger Binding="{Binding IsMouseOver,ElementName=image}" 
                            Value="True">
                   <DataTrigger.EnterActions>
                     <BeginStoryboard>
                       <Storyboard>
                         <DoubleAnimation Storyboard.TargetProperty="Height" 
                                          To="71"  Duration="0:0:0.3" />
                       </Storyboard>
                     </BeginStoryboard>
                   </DataTrigger.EnterActions>
               </DataTrigger>
            </Style.Triggers>
         </Style>
      </WrapPanel.Style>
    </WrapPanel>
    
    <Image Name="image">
      <Image.Triggers>
        <EventTrigger RoutedEvent="MouseEnter">
          <BeginStoryboard>
            <Storyboard>
               <DoubleAnimation Storyboard.TargetProperty="Height" To="71"
                                Duration="0:0:0.3" />     
            </Storyboard>
          </BeginStoryboard>
        </EventTrigger>
      </Image.Triggers>
    </Image>
    

    请注意,您必须为Image 命名(例如image)。 WrapPanel 的&lt;DoubleAnimation&gt; 已删除。我们没有使用EventTrigger,而是使用DataTrigger 监听IsMouseOver 属性。您还可以指定DataTrigger.ExitActions 以在IsMouseOver 为假(等于MouseLeave)时开始动画。

    【讨论】:

    • 哇,非常感谢!我非常感谢这一点,这非常有助于我最终了解如何仅通过 xaml 管理动画。再次感谢您!
    • 小修正。 x:Reference 是在 .Net 4.0 中引入的,而不是在 .Net 4.5 中引入的。
    • 有没有关于这方面的官方 MSFT 文档?他们在哪里描述了如何从孩子事件中为父母制作动画?没有 SO,如何了解这一点?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-25
    • 1970-01-01
    • 2021-02-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多