WPF事件触发器更改其他UI元素

时间:2014-09-28 09:10:00

标签: c# wpf xaml triggers event-triggers

我在我的XAML中使用ListBox定义了ItemTemplate。 在我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>

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

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

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

感谢您的帮助!!

1 个答案:

答案 0 :(得分:5)

有两种方法可以解决这个问题。第一个是在.NET 4.0 for WPF中使用{x:Reference}一个功能。如果您的应用程序面向.NET 4.0,则应遵循此方法。我们的想法是将Storyboard.Target设置为您要设置动画的对象(在本例中为WrapPanel)。虽然我们可以Binding使用Storyboard.Target,但我们无法使用RelativeSourceElementName来设置绑定源,因为Storyboard(或时间轴)不是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的<DoubleAnimation>已删除。我们使用EventTrigger监听DataTrigger属性,而不是使用IsMouseOver。您还可以指定DataTrigger.ExitActions以在IsMouseOver为假(等于MouseLeave)时开始制作动画。