利用依赖属性实现模式窗体的自动关闭

    先来看一下什么是依赖属性(Dependency Properties):

    在WPF引入了一种新的属性类型,称作“依赖属性”,它可以用在外观风格、自动化数据绑定以及动画等方面。依赖属性依赖多个能够在任意时刻及时确定属性值的提供器(provider),这些提供器可以是一个不断改变属性值的动画,也可以是一个可以将属性值传递到子元素的父元素。它的最大的特点无疑是它能够提供变更通知的能力。

    依赖属性的使用GetValue和SetValue进行值操作。而在他们内部使用了一个高效的存储结构(意思大概是说,依赖属性通过Register方法注册到一个数据结构中,这个结构的存取效率很好,因此通过那两个方法操作依赖属性,相应的开销也会很小),且IsDefaultProperty是静态字段,这使得依赖属性的实现相对于一般的.NET属性而言,由于不用为每个实例都分配内存,从而节省内存的开销。

     依赖属性带来的好处不仅仅在内存使用方面,它还集中化并且标准化了许多属性的实现代码,这些属性实现代码有用来检查线程访问的,也有用来引发重绘所含元素的。例如,在元素属性值变更的时候(如Button的Background属性),元素需要被重绘,这可以通过传递FrameworkPropertyMatadataOptions.AffectsRender标志到重载的DependencyProperty.Register方法来实现。此外,依赖属性还允许三种重要的特性:变更通知、属性值继承以及对多种提供器的支持。

    在设计一些WPF客户端程序时,我们不可避免的被要求做一个启动的欢迎界面,我们可以在主窗体启动时启动一个副窗体来实现。这个窗体我们可以以模式和非模式的对话框的形式来呈现。不过由于在启动欢迎界面的窗体完成后才能进入主窗体,因此需要使用模式对话框。这里我们要用到Windows下的ShowDialog()方法,它的作用就是以模式窗体的方式来呈现目标窗体。

    在主窗体通过ShowDialog()方法启动了副窗体后,控制权就交给了副窗体了,这样什么时候关闭副窗体,就得靠副窗体自身的逻辑来实现了。而且由于ShowDialog()方法是一个阻塞方法,也就是说主窗体在启动副窗体以后,会一直阻塞到副窗体的关闭以后才能向前执行其他步骤。这样我们就得在适当的时候关闭副窗体以取消阻塞。即要处理窗体的Close()方法。

   思路:【副窗体】

      1、 定义一个依赖属性,在这个属性中实现窗体的Close()方法的调用;

      2、 设置一个触发器以修改依赖属性的值实现窗体的关闭功能。

     具体实现:

      1、 定义一个IsClosedProperty的bool型的依赖属性,同时在这里注册了一个委托处理方法IsClosedChanged(),在这个方法里我们实现了调用窗体的Close()方法以关闭窗体。

 

注册依赖属性
//注册一个依赖属性

public static readonly DependencyProperty IsClosedProperty = DependencyProperty.Register("IsClosed", typeof(bool), typeof(Logoin), new PropertyMetadata(IsClosedChanged));

//这个方法实现调用窗体的Close()方法

private static void IsClosedChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e){

((Logoin)sender).Close();
//窗体的Close()方法

}

public bool IsClosed{//.net机制的属性

get { return (bool)GetValue(IsClosedProperty); }

set { SetValue(IsClosedProperty, value); }

}

 

 

  现在我们已经定义好了一个公共的属性,只要IsColsed的值一改变就会调用Close()方法实现窗体关闭了。不过我们在那儿来改变这个属性值呢,那是事件触发器。

  2、 事件触发器调用

    这儿我们调用了Loaded事件触发器,表示在窗体装载完成后就开始触发事件了,因为我们的启动欢迎窗口界面只能有一个短暂的停留来呈现给用户,所以我们假定是在一分钟时间内来实现关闭。同时作用了自定义状态变换动作。GoToStateAction调用Logn_in状态。

 

<i:Interaction.Triggers>

<i:EventTrigger EventName="Loaded">

<ei:GoToStateAction StateName="logn_in"/>

</i:EventTrigger>

</i:Interaction.Triggers>

 

 

3、 在自定义的视觉状态中设置先前定义的IsColsed属性

 

自定义视觉状态
<VisualStateManager.VisualStateGroups>

<VisualStateGroup x:Name="VisualStateGroup">

<VisualState x:Name="logn_in">

<Storyboard>

……

<ObjectAnimationUsingKeyFrames BeginTime="0:0:0.9" Storyboard.TargetName="LogoForm"

Storyboard.TargetProperty
="(IsClosed)">

<DiscreteObjectKeyFrame KeyTime="0:0:1">

<DiscreteObjectKeyFrame.Value>

<System:Boolean >True</System:Boolean>

</DiscreteObjectKeyFrame.Value>

</DiscreteObjectKeyFrame>

</ObjectAnimationUsingKeyFrames>

……

</Storyboard>

</VisualState>

</VisualStateGroup>

</VisualStateManager.VisualStateGroups>

 

 

    这儿调用了窗体的IsClosed的依赖属性,成功的实现了自己的关闭。这里只是依赖属性运行的一个小的例子,实际上在WPF程序设计中大量使用了依赖属性,这样不仅给我们的程序设计带来不错的感官享受,同时也提高了程序的运行性能。

4、 在主窗体中调用ShowDialog()方法启动欢迎窗体。成功执行一段动画后顺利地关闭了副窗体。效果如图:

clip_image002[4]示例代码

posted @ 2010-05-29 15:41  suyan010203  Views(1896)  Comments(3Edit  收藏