使用动态参数绑定样式中的ElementName。重用样式

时间:2014-11-28 10:09:56

标签: c# wpf xaml

我有一个问题。 我在TextBlocks的WPF设计器(XML)中创建了一个样式。在两个图像控件中的任何一个上触发IsMouseOver事件后,我的textBlocks会改变其位置。此样式用于某些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,其中“Binding ElementName”不同,例如image3和image4。 我认为如果有可能使用某种类型的动态参数或参数重用这种风格,那就太棒了。 我搜索任何解决方案只作为xml代码,没有任何C#(我使用C#和WPF)或转换器实现。

提前致谢。

2 个答案:

答案 0 :(得分:2)

这是纯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

答案 1 :(得分:0)

你可以定义附加的属性来保存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 - 它需要一些代码隐藏来定义附加属性,但我怀疑它是一种完全避免它的优雅方法。