欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

WPF教程(九)样式入门二

程序员文章站 2022-07-13 23:03:15
...

在我看来,WPF的Trigger是一个非常聪明的设计,Winform要大量的代码才绘出的皮肤,在这里轻松就能搞定。但我也不是鄙视Winform,它也有自己的优势,抛开界面美化,在一些控件的使用上,明显比WPF好用,就拿DateTimePicker控件,一个能具体到小时,一个只有日期。我坚信存在即合理,各有用处。

言归正传,触发器,是System.Windows.TriggerBase的派生类的实例,可以根据属性或事件发生变化时进行响应,并自动调整样式。触发器在Style的 Triggers集合中定义,每个样式都可以有任意多个触发器。

PropertyTrigger,属性触发器是在当某个依赖属性的值发生变化时触发执行一个Setter的集合,当属性失去这个值时,这些被处罚执行的Setter集合会自动被撤销。

<StackPanel>  
    <Button Content="TriggerBtn" Click="Trigger_Click">
        <Button.Resources >
            <Style TargetType="Button">
            <Style.Triggers>
                <Trigger Property="IsMouseOver" Value="True">
                    <Setter Property="RenderTransform">
                        <Setter.Value>
                            <!-->旋转角度<-->
                            <RotateTransform Angle="10"></RotateTransform>
                            </Setter.Value>
                        </Setter>
                            <!-->原点比例位置<-->
                        <Setter Property="RenderTransformOrigin" Value="0.5,0.5"></Setter>
                    <Setter Property="Background" Value="#FF0CC030" />
                </Trigger>
            </Style.Triggers>
            </Style>
        </Button.Resources>
    </Button>
</StackPanel>

MultiPropertyTTrigger ,多条件属性触发器是在满足多个依赖属性的值发生变化时触发执行一个Setter的集合,当属性失去这个值时,这些被处罚执行的Setter集合会自动被撤销。

<StackPanel>
    <Button Content="TriggerBtn" Click="Trigger_Click" >
        <Button.Resources >
             <Style TargetType="Button">
                 <Style.Triggers>
                     <MultiTrigger>
                          <MultiTrigger.Conditions>
                               <Condition Property="IsMouseOver" Value="True"/>
                               <Condition Property="IsPressed" Value="True"/>
                          </MultiTrigger.Conditions>
                          <Setter Property="RenderTransform">
                               <Setter.Value>
                               <!-->旋转角度<-->
                                   <RotateTransform Angle="10"/>
                               </Setter.Value>
                          </Setter>
                          <!-->原点比例位置<-->
                          <Setter Property="RenderTransformOrigin" Value="0.5,0.5"/>
                          <Setter Property="Background" Value="#FF0CC030" />
                     </MultiTrigger>
                 </Style.Triggers>
             </Style>
        </Button.Resources>
    </Button>
</StackPanel>

DataTrigger,数据触发器和属性触发器除了面对的对象类型不一样外其它完全相同。数据触发器是来检测非依赖属性(也就是用户自定义的.NET属性)值发生变化时来触发并调用符合条件的一系列Setter集合,看下面两个例子:

1.点击Button改变文本颜色

<Window.Resources>      
    <Style x:Key="styData" TargetType="{x:Type Label}">
        <Style.Triggers>
            <DataTrigger  Binding="{Binding Path=Text}" Value="Hello World">
                <!--如果后台类的属性Text等于Hello World时,就会触发属性,将字体颜色改变红色-->
                <Setter Property="Foreground" Value="Red"></Setter>
            </DataTrigger>
        </Style.Triggers>
    </Style>
</Window.Resources>
<Grid>
    <Grid Background="Bisque">
        <Label Content="name:lbl" Height="37" HorizontalAlignment="Left" Margin="224,110,0,0" Name="lbl" VerticalAlignment="Top" Width="auto" Style="{StaticResource styData}" />
        <Button Content="点击变色" Height="auto" HorizontalAlignment="Left" Margin="224,204,0,0" Name="btnPrint" VerticalAlignment="Top" Width="auto" Click="btnPrint_Click" />
    </Grid>  
</Grid>
class changetext
{
    public string _text;
    public string Text
    {
        get { return _text; }
        set { _text = value; }
    }
}
public partial class MainWindow : Window
{

    changetext st = new changetext();
    public MainWindow()
    {
        InitializeComponent();

    }
    private void btnPrint_Click(object sender, RoutedEventArgs e)
    {
        st.Text = "Hello World";
        lbl.DataContext = st;
    }
}

2. ListBox的内容不同颜色显示

<Window.Resources>
    <Style TargetType="ListBoxItem">
        <Style.Triggers>
            <DataTrigger Binding="{Binding Path=Publisher}" Value="Wrox Press">
                <Setter Property="Background" Value="Red"/>
            </DataTrigger>
            <DataTrigger Binding="{Binding Path=Publisher}" Value="Dummies">
                <Setter Property="Background" Value="Yellow"/>
            </DataTrigger>
            <DataTrigger Binding="{Binding Path=Publisher}" Value="Sybex">
                <Setter Property="Background" Value="LightBlue"/>
            </DataTrigger>
        </Style.Triggers>
    </Style>
</Window.Resources>
<Grid>
    <ListBox x:Name="list1" Width="300" Height="200" Margin="12,87,191,24" Grid.Row="0" />
</Grid>
class Book
{
    public string Title { get; set; }    //书名
    public string Publisher { get; set; }   //出版商
    public override string ToString()//不可能显示一个对象,系统会调用对象的ToString()来显示
    {
        return Title;
    }
}
public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        list1.Items.Add(new Book
        {
            Title = "Professional C# 4.0",
            Publisher = "Wrox Press"
        });
        list1.Items.Add(new Book
        {
            Title = "C# 2008 for Dummies",
            Publisher = "Dummies"
        });
        list1.Items.Add(new Book
        {
            Title = "Mastering Integrated HTML and CSS",
            Publisher = "Sybex"
        }); 
    }
}

MultiDataTrigger,在绑定数据满足一组条件时一项或多项属性值执行操作,我们将上述例2的资源样式改成MultiDataTrigger,明显不是全部都能触发。

<Window.Resources>
    <Style TargetType="ListBoxItem">
        <Style.Triggers>
        <MultiDataTrigger>
            <MultiDataTrigger.Conditions>
                <Condition  Binding="{Binding Path=Publisher}" Value="Wrox Press"/>
                <Condition  Binding="{Binding Path=Publisher}" Value="Dummies"/>                      
            </MultiDataTrigger.Conditions>
            <Setter Property="Background" Value="Red"/>              
        </MultiDataTrigger>
        <MultiDataTrigger>
            <MultiDataTrigger.Conditions>
                <Condition Binding="{Binding Path=Publisher}" Value="Dummies"/>
                <Condition Binding="{Binding Path=Publisher}" Value="Sybex"/>
            </MultiDataTrigger.Conditions>
            <Setter Property="Background" Value="Yellow"/>
        </MultiDataTrigger>            
        <DataTrigger Binding="{Binding Path=Publisher}" Value="Sybex">
            <Setter Property="Background" Value="LightBlue"/>
        </DataTrigger>
    </Style.Triggers>
    </Style>
</Window.Resources>

EventTrigger,在事件发生时**,即触发路由事件时会被调用。

<StackPanel>
    <Button Content="TriggerBtn">
        <Button.Resources>
            <Style TargetType="{x:Type Button}">
                <Style.Triggers>
                    <EventTrigger RoutedEvent="Mouse.MouseEnter" >
                        <BeginStoryboard>
                            <!--一个为其所包含的动画提供目标信息的容器。除非动画放在Storyboard中,负责不能在XMAL中被实例化-->
                            <Storyboard>
                                 <DoubleAnimation Duration="00:00:10" Storyboard.TargetProperty="FontSize"  To="18" />
                            </Storyboard>
                        </BeginStoryboard>
                    </EventTrigger>
                    <EventTrigger RoutedEvent="Mouse.MouseLeave">
                        <EventTrigger.Actions>
                            <BeginStoryboard>
                                <Storyboard>
                                     <DoubleAnimation Duration="00:00:10" Storyboard.TargetProperty="FontSize"  To="12" />
                                 </Storyboard>
                             </BeginStoryboard>
                        </EventTrigger.Actions>
                    </EventTrigger>
                </Style.Triggers>
            </Style>
        </Button.Resources>
    </Button>
</StackPanel>