[笔记/简译]WPF的新特性——依赖属性(2)

来源:互联网 发布:淘宝的商业价值 编辑:程序博客网 时间:2024/05/22 06:05

变更通知

 

       在依赖属性值发生变化的时候,WPF能够自动触发一些依赖这个属性元数据的动作,这些动作可以是重绘相应的元素、更新当前布局以及刷新数据绑定等。由变更通知实现的一个有趣的特性被称作“属性触发器”(property triggers),它允许我们不编写程序代码就可以在属性值发生改变的时候执行自定义动作。例如,我们把鼠标悬停在About Dialog(参看之前发布的文章)的按钮上时,按钮的文本立刻变成蓝色;移开鼠标,按钮的文本又恢复成黑色。为了实现这样的想法,我们在没有属性触发器的情况下,可以为每一个按钮附加事件处理器。鼠标悬停的事件是MouseEnter,鼠标移开的事件是MouseLeave

 

<Button MouseEnter="Button_MouseEnter" MouseLeave="Button_MouseLeave"

MinWidth="75" Margin="10">Help</Button>

<Button MouseEnter="Button_MouseEnter" MouseLeave="Button_MouseLeave"

MinWidth="75" Margin="10">OK</Button>

 

       对应的两个事件处理函数为:

 

//  当鼠标悬停在按钮上时,将按钮的背景颜色改为蓝色

private void Button_MouseEnter(object sender, MouseEventArgs e)

{

Button b = sender as Button;

if (b != null) b.Foreground = Brushes.Blue;

}

 

//  当鼠标离开按钮时,恢复按钮的背景颜色

private void Button_MouseLeave(object sender, MouseEventArgs e)

{

Button b = sender as Button;

if (b != null) b.Foreground = Brushes.Black;

}

 

       如果使用属性触发器,我们可以大幅简化上面的实现,仅通过XAML就可以完成相同的任务:

 

<Trigger Property="IsMouseOver" Value="True">

<Setter Property="Foreground" Value="Blue" />

</Trigger>

 

       触发器可以作用在按钮的IsMouseOver属性上,它的值在MouseEnter事件被触发的时候变为true,在MouseLeave被触发的时候变为false。值得注意的是,我们并不需要在IsMouseOver变为false时将Foreground恢复成黑色,这个工作完全由WPF自动完成。

 

       触发器需要附加在每一个按钮上,但不幸的是,由于WPF 3.0中的人为限制,我们不能像在Button这样的元素上直接应用触发器,而只能将其应用在其Style对象内部,如下:

 

<Button MinWidth="75" Margin="10" Content="Help">

    <Button.Style>

        <Style TargetType="{x:Type Button}">

            <Style.Triggers>

                <Trigger Property="IsMouseOver" Value="True">

                    <Setter Property="Foreground" Value="Blue" />

                </Trigger>

            </Style.Triggers>

        </Style>

    </Button.Style>

</Button>

 

       属性触发器只是WPF支持的三类触发器中的一类,其它两类是数据触发器和事件触发器,将会在以后介绍。此外,尽管FrameworkElementTriggers属性是一个TriggerBase类型(三类触发器的基类)的读/写集合,但其在WPF 3.0中只能包含事件触发器,这是由于WPF团队来不及完全实现造成的,因此,如果向该集合添加属性触发器或数据触发器,将导致运行时异常。(尚未在VS2008中试验这么做是否会出现异常)

 

       (如果我为Button同时设置MouseEnter事件处理器和IsMouseOver的触发器会是什么结果呢?对于上例,修改XAML代码如下:

 

<Button MinWidth="75" Margin="10" Content="Help" MouseEnter="Button_MouseEnter">

    <Button.Style>

        <Style TargetType="{x:Type Button}">

            <Style.Triggers>

                <Trigger Property="IsMouseOver" Value="True">

                    <Setter Property="Foreground" Value="Blue" />

                </Trigger>

            </Style.Triggers>

        </Style>

    </Button.Style>

</Button>

 

并为其添加事件处理方法:

 

private void Button_MouseEnter(object sender, MouseEventArgs e)

{

System.Threading.Thread.Sleep(1000);

}

 

       运行后将鼠标放在Button上面,可以发现按钮的文本颜色在1秒钟后变成蓝色。这说明按钮的事件处理方法先于风格触发器执行。同理,修改上面的事件处理方法如下:

 

private void Button_MouseEnter(object sender, MouseEventArgs e)

{

Button b = sender as Button;

if (b != null) b.Foreground = Brushes.Red;

}

 

       运行后将鼠标放在按钮上面,可以看到其文本颜色变为红色,且当鼠标从按钮上移开,文本并不变色。如果想要解释这种想象的产生原因,需要了解后面的一些知识。)

原创粉丝点击