WPF 事件触发器更改其他 UI 元素
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/26083342/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
WPF Event Trigger Change Other UI element
提问by Jacob
I defined ListBoxin my XAML which uses ItemTemplate.
Inside the ItemTemplateI placed Image.
我ListBox在我的 XAML 中定义了使用ItemTemplate. 在ItemTemplateI 放置的 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>
When the mouse enter the image I want to begin storyboard on that image height andon the WrapPanelwhich I defined inside the ItemsPanelTemplate.
当鼠标进入图像我想开始对图像高度故事板和对WrapPanel我里面的定义ItemsPanelTemplate。
When the mouse enter to this image I got the following exception: "'itmTempPanel' name cannot be found in the name scope of 'System.Windows.Controls.Image'."
当鼠标进入该图像时,出现以下异常:“在‘System.Windows.Controls.Image’的名称范围内找不到‘itmTempPanel’名称。”
How can I change other element property from element that begin the storyboard.
如何从开始故事板的元素更改其他元素属性。
Thank you for your help !!
感谢您的帮助 !!
回答by King King
There are 2 ways to solve this. The first is using {x:Reference}a feature in .NET 4.0 for WPF. You should follow this approach if your application targets .NET 4.0. The idea is setting the Storyboard.Targetto the object you want to animate (in this case is the WrapPanel). Although we can use Bindingfor Storyboard.Targetbut we cannot use RelativeSourceor ElementNameto set the binding source because Storyboard(or Timeline) is not a FrameworkElement (or FrameworkContentElement). The only way to specify the source is setting the Sourceproperty. However we can normally set this to a StaticResourceor DynamicResourceor directly (using element syntax). It's fortunate that the {x:Reference}was introduced in .NET 4.0 and this can help you reference any named object inside XAML (the way it works is not like ElementName). Here is the code for the first approach:
有2种方法可以解决这个问题。第一个是将{x:Reference}.NET 4.0 中的一项功能用于 WPF。如果您的应用程序面向 .NET 4.0,则应遵循此方法。这个想法是将 设置为Storyboard.Target要设置动画的对象(在本例中是WrapPanel)。虽然我们可以使用BindingforStoryboard.Target但我们不能使用RelativeSourceorElementName来设置绑定源,因为Storyboard(或时间轴)不是 FrameworkElement(或 FrameworkContentElement)。指定来源的唯一方法是设置Source属性。然而,我们通常可以将其设置为 a StaticResourceor DynamicResourceor 直接(使用元素语法)。幸运的{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" />
The second approach is based on DataTrigger. However this trigger is not for Image, it's exactly for the WrapPanel. But now the ElementNamecan be used to bind the Trigger source to the Image. So this approach is usable when {x:Reference}is not supported.
第二种方法是基于DataTrigger. 但是,此触发器不适用于Image,它完全适用于WrapPanel。但是现在ElementName可以用于将 Trigger 源绑定到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>
Note that you have to give the Imagea name (such as image). The <DoubleAnimation>for the WrapPanel is removed. Instead of using EventTrigger, we used DataTriggerlistening to IsMouseOverproperty. You can also specify the DataTrigger.ExitActionsto start animating when IsMouseOveris false (equal to MouseLeave).
请注意,您必须提供Image一个名称(例如image)。在<DoubleAnimation>对WrapPanel被删除。EventTrigger我们没有使用,而是使用了DataTrigger监听IsMouseOver属性。您还可以指定DataTrigger.ExitActions在IsMouseOver为 false(等于MouseLeave)时开始动画。

