如何在保持控件的基本行为的同时支持依赖于触发器的视觉效果?

时间:2014-03-17 13:52:11

标签: c# wpf xaml

我有这个自定义控件:

<UserControl x:Class="MyNs.MyControl"
    <Border DataContext="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}">
        <Grid Margin="5,0,5,0">
            ...
            <TextBlock Text="{Binding Path=ControlData.DependencyPropertyOne}" />
            <TextBlock Text="{Binding Path=ControlData.DependencyPropertyTwo}" />
            <TextBlock Text="{Binding Path=ControlData.DependencyPropertyThree}" />
            ...
        </Grid>
    </Border>
</UserControl>

我按如下方式使用它:

<UserControl x:Class="MyNs.ParentControl"
    <Grid>
        <Grid.Resources>
            <Style TargetType="{x:Type my:MyControl}">
                <Style.Triggers>
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter Property="Template">
                            <Setter.Value>
                                <ControlTemplate>
                                    <Border Background="Red" BorderThickness="6"></Border>
                                </ControlTemplate>
                            </Setter.Value>
                        </Setter>
                    </Trigger>
                </Style.Triggers>
        </Grid.Resources>

        <my:MyControl ControlData="{Binding CdOne}"/>
        <my:MyControl ControlData="{Binding CdTwo}"/>
        <my:MyControl ControlData="{Binding CdThree}"/>
        <my:MyControl ControlData="{Binding CdFour}"/>
        <my:MyControl ControlData="{Binding CdFive}"/>
        <my:MyControl ControlData="{Binding CdSix}"/>
    </Grid>
</UserControl>

但是当我用鼠标悬停时,内容会被红色背景替换(所有TextBlock都会消失)。

那么如何让主机控件在保持控件的基本行为的同时改变一些依赖于触发器的视觉效果?

2 个答案:

答案 0 :(得分:1)

您的触发器需要位于UserControl内,或者您的UserControl需要具有依赖属性(例如&#34; BackgroundBrush&#34;)外部事物可以通过触发器设置你的控制在渲染时会尊重。这就是TemplateBinding对其有用的内容。

使用你的控件的任何东西都应该不知道里面的模板,应该只是设置公共属性。

如果您真的希望将控件的逻辑与其外观区分开来,那么您应该创建一个适当的无外观Control,而不是UserControl,并且消费者可以提供自己的控件模板他们想要的。这是标准WPF控制的方法。

答案 1 :(得分:1)

override the ControlTemplate of MyControl上有IsMouseOver,因此无法显示包含您内容的实际模板。

理想情况下,此触发器应该在MyControl中。但是,即使您想从外部进行操作,也需要在边框内添加ContentPresenter来托管您的内容。

用这一个替换ControlTemplate内部样式:

<ControlTemplate>
   <Border Background="Red" BorderThickness="6">
       <ContentPresenter
            Content="{TemplateBinding ContentControl.Content}"
            ContentTemplate="{TemplateBinding ContentControl.ContentTemplate}"
            ContentStringFormat="{TemplateBinding ContentControl.ContentStringFormat}"
            HorizontalAlignment="{TemplateBinding Control.HorizontalContentAlignment}"
            VerticalAlignment="{TemplateBinding Control.VerticalContentAlignment}"
            SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" />
    </Border>
</ControlTemplate>