我应该在哪里定义和设置这些样式

时间:2015-11-14 15:56:56

标签: wpf custom-controls datatrigger

在下图中,您可以看到我当前正在创建的自定义控件,以便尽可能多地了解控件创建的整个过程。

enter image description here

目前,我试图通过有效地将重复样式元素重构为单独的样式来简化xaml,并在禁用它们所在的按钮时实现图像的禁用外观。

在下面的xaml中,您可以看到我创建的按钮样式和图像的数据触发器。从理论上讲,两者都适用于左侧的第二个按钮,但很明显它们并不存在。

我认为基本的样式定义是正确的,但可能是因为它们位于不正确的位置。任何人都可以建议我目前做错了什么。

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:local="clr-namespace:ViewToLearn.WpfControls">


    <Style TargetType="{x:Type Image}">
        <Style.Triggers>
            <DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType={x:Type UIElement}, AncestorLevel=1}, Path=IsEnabled}"
                         Value="False">
                <Setter Property="Opacity"
                        Value="0.2"></Setter>
            </DataTrigger>
        </Style.Triggers>
    </Style>


    <Style TargetType="{x:Type Button}">
        <Setter Property="BorderBrush"
                Value="Transparent" />
        <Setter Property="Background"
                Value="Transparent" />
        <Setter Property="BorderThickness"
                Value="0" />
        <Setter Property="Margin"
                Value="4" />
    </Style>

    <Style TargetType="{x:Type local:VtlDataNavigator}">


        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type local:VtlDataNavigator}">
                    <StackPanel Orientation="Horizontal">
                        <Button BorderBrush="Transparent"
                                Background="Transparent"
                                BorderThickness="0">
                            <StackPanel Margin="4">
                                <Image Source="/ViewToLearn.WpfControls;component/Resources/Images/button_rounded_blue_first24.png" />
                            </StackPanel>
                        </Button> <!-- This is the button that should be influenced by the style and trigger defined above, but clearly it isn't -->
                        <Button IsEnabled="False">
                            <StackPanel Margin="4">
                                <Image Source="/ViewToLearn.WpfControls;component/Resources/Images/button_rounded_blue_previous24.png" />
                            </StackPanel>
                        </Button>
                        <TextBox Text="{Binding Path=RecordIndex,RelativeSource={RelativeSource TemplatedParent}}"
                                 VerticalAlignment="Center"
                                 IsReadOnly="True"
                                 BorderThickness="0"
                                 Margin="4" />
                        <TextBlock Text="of"
                                   VerticalAlignment="Center"
                                   Margin="4" />
                        <TextBlock Text="{Binding Path=RecordCount,RelativeSource={RelativeSource TemplatedParent}}"
                                   VerticalAlignment="Center"
                                   Margin="4" />
                        <Button BorderBrush="Transparent"
                                Background="Transparent"
                                BorderThickness="0">
                            <StackPanel Margin="4">
                                <Image Source="/ViewToLearn.WpfControls;component/Resources/Images/button_rounded_blue_next24.png" />
                            </StackPanel>
                        </Button>

1 个答案:

答案 0 :(得分:0)

您的第二个按钮有IsEnabled="false" 这有所不同。

但是如果您希望所有按钮的背景相同,无论是否启用,您都必须进入触发器

使用触发器生成默认样式和模板的最佳方法是在窗口中放置一个虚拟/测试按钮,右键单击它,编辑模板/编辑副本。
VS将生成很多代码。你会在&#34; full&#34;里面看到模板&#34;按钮+触发器。

内部有一个触发器,用于禁用时的不同外观

<Setter Property="Template" >
    <Setter.Value>
        <ControlTemplate TargetType="{x:Type ButtonBase}">
            <Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
                <ContentPresenter x:Name="contentPresenter" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" ContentStringFormat="{TemplateBinding ContentStringFormat}" Focusable="False" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
            </Border>
            <!-- ... -->
            <ControlTemplate.Triggers>
                <Trigger Property="IsEnabled" Value="False">
                    <Setter Property="Background" TargetName="border" Value="#FFF4F4F4"/>
                    <Setter Property="BorderBrush" TargetName="border" Value="#FFADB2B5"/>
                    <Setter Property="TextElement.Foreground" TargetName="contentPresenter" Value="#FF838383"/>
                </Trigger>
            </ControlTemplate.Triggers>
        </ControlTemplate>
    </Setter.Value>
</Setter>

这个模板你可以从中获取灵感来更新你的风格(禁用时没有触发器):

<Style TargetType="{x:Type Button}">
    <Setter Property="BorderBrush"
        Value="Transparent" />
    <Setter Property="Background"
        Value="Transparent" />
    <Setter Property="BorderThickness"
        Value="0" />
    <Setter Property="Margin"
        Value="4" />
    <Setter Property="Template" >
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type ButtonBase}">
                <Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
                    <ContentPresenter x:Name="contentPresenter" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" ContentStringFormat="{TemplateBinding ContentStringFormat}" Focusable="False" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                </Border>
                <!-- no trigger int he template -->
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

有关您的代码的注意事项,因为您似乎很想学习:

  1. 不必为每个按钮设置Background,BorderThickness,BorderBrush,它已经在您的Button样式中完成
  2. 每个StackPanel周围的Image都相同,可以放在ContentPresenter标记
  3. 周围的模板内
  4. 如果VtlDataNavigatorUsercontrol,您可以将<ControlTemplate TargetType="{x:Type local:VtlDataNavigator}">的所有内容放在<UserControl>标记内。
    它使控件更具可重用性(不必在每个Window中为控件提供模板)
  5. 此致