利用依赖属性实现模式窗体的自动关闭
先来看一下什么是依赖属性(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()方法启动欢迎窗体。成功执行一段动画后顺利地关闭了副窗体。效果如图: