使用动态参数在样式中绑定元素名称.重用样式
本文关键字:样式 元素 绑定 参数 动态 | 更新日期: 2023-09-27 18:32:17
我有一个问题。我在 WPF 设计器 (XML) 中为 TextBlock 创建了一个样式。在两个图像控件中的任何一个上触发 IsMouseOver 事件后,我的 textBlocks 会更改其位置。此样式用于某些文本块。
<Style x:Key="movingTextBlocksStyle" TargetType="{x:Type TextBlock}">
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=image1, Path=IsMouseOver}" Value="True">
<Setter Property="RenderTransform">
<Setter.Value>
<TranslateTransform/>
</Setter.Value>
</Setter>
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="(UIElement.RenderTransform).(TranslateTransform.X)" From="0" To="-125"/>
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
</DataTrigger>
<DataTrigger Binding="{Binding ElementName=image2, Path=IsMouseOver}" Value="True">
<Setter Property="RenderTransform">
<Setter.Value>
<TranslateTransform/>
</Setter.Value>
</Setter>
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="(UIElement.RenderTransform).(TranslateTransform.X)" From="0" To="-125"/>
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
</DataTrigger>
</Style.Triggers>
</Style>
此样式将用作:
<TextBlock x:Name="textBlock1" Style="{StaticResource movingTextBlocksStyle}"/>
<TextBlock x:Name="textBlock2" Style="{StaticResource movingTextBlocksStyle}"/>
我的问题是我想将这种样式重用于另一个 textBlocks:textBlock3 和 textBlock4,其中"绑定元素名称"不同,例如 image3 和 image4。我想过,如果有任何可能用某种类型的动态参数或参数重用这种风格,那就太好了。我搜索任何解决方案仅作为 xml 代码,没有任何 C#(我将 C# 与 WPF 一起使用)或转换器实现。
提前谢谢。
下面是纯 XAML 解决方案:
在数组中收集文本块所依赖的所有控件,并将其设置为数据上下文:
<Image x:Name="image1"/>
<Image x:Name="image2"/>
<TextBlock Style="{StaticResource movingTextBlocksStyle}">
<TextBlock.DataContext>
<x:Array Type="system:Object">
<x:Reference>image1</x:Reference>
<x:Reference>image2</x:Reference>
</x:Array>
</TextBlock.DataContext>
</TextBlock>
您需要记住相应地更改TextBlock
属性上的所有绑定,因为不再继承数据上下文。然后在样式定义中使用相应的数组索引绑定:
<DataTrigger Binding="{Binding [0].IsMouseOver}" Value="True">...</DataTrigger>
...
<DataTrigger Binding="{Binding [1].IsMouseOver}" Value="True">...</DataTrigger>
system:
前缀命名空间为 clr-namespace:System;assembly=mscorlib
。
您可以
定义附加属性,这些属性将保存TextBox
所依赖的控件,如下所示(我将仅使用一个属性来保持简短):
static class Helper
{
public static object GetImage(DependencyObject obj)
{
return (object)obj.GetValue(ImageProperty);
}
public static void SetImage(DependencyObject obj, object value)
{
obj.SetValue(ImageProperty, value);
}
public static readonly DependencyProperty ImageProperty =
DependencyProperty.RegisterAttached(
"Image",
typeof(object),
typeof(Helper),
new PropertyMetadata(null));
}
然后,在数据触发器中,使用附加属性进行绑定:
...
<DataTrigger Binding="{Binding Path=(local:Helper.Image).IsMouseOver, RelativeSource={RelativeSource Self}}" Value="True">
...
最后,将属性值设置为TextBlock
所依赖的控件:
<Image x:Name="image1"/>
...
<TextBlock local:Helper.Image="{Binding ElementName=image1}"
Style="{StaticResource movingTextBlocksStyle}"/>
此解决方案不是纯粹的 XAML - 它需要一些代码隐藏来定义附加的属性,但我怀疑是否有一种优雅的方法可以完全避免它。