在开发Silverlight或者WPF项目时,当我们调用Web服务来加载一些数据时,由于数据量比较大需要较长的时间,需要用户等待,为了给用户友好的提示和避免用户在加载数据过程中进行重复操作,我们通常使用BusyIndicator这个控件来锁定当前页面。然而,有时候BusyIndicator这个控件的风格和我们的界面风格并不搭配,而且修改起来也比较麻烦,今天我们就来自己写一个BusyIndicator控件,实现自定义的忙碌提示。

后面会提供源码下载。

 一、实现基本原理及最终效果

  我们先来看下面这段代码,如图:

我们添加了三个矩形在Grid中,我们设置了矩形的宽度和高度,那么矩形会怎么显示呢?从上到下顺序显示吗?NO!不是这样的,我们来看看显示结果:

三个矩形层叠在了一起,按照代码的顺序,依次从下往上显示,代码中放在最后的矩形显示在最顶层。这是Grid的一个特性,当然在Canvas中也可以层叠显示,不过不是居中显示,是右上脚对齐显示的。如果是StackPanel则是从上到下一次显示。

根据这个特性,我们知道在Grid中后添加的UI元素会显示在其他元素的最顶层,所以我们可以在运行时通过代码来动态的向Grid中添加元素,并且这个元素处于最顶层,从而可以遮挡其他页面元素。

下面我们来看看最终的实现效果:

是不是有一种中国风的味道啊!下面我们来详细说明实现方法。

 二、自定义BusyIndicator的具体实现

  这里我是用Silverlight来演示,用WPF也是一样的。首先新建项目,添加一个Silverlight user Control,这里我起的名字就叫Load,页面XAML代码如下:

<UserControl x:Class="SilverlightBusy.Load"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ed="http://schemas.microsoft.com/expression/2010/drawing"
mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="400">
<UserControl.Resources>
<Storyboard x:Name="fadeStoryboard">
<DoubleAnimation x:Name="fadeAnimation" BeginTime="00:00:00" Storyboard.TargetName="LayoutRoot" Storyboard.TargetProperty="Opacity" From="0.9" To="0" Duration="0:0:01">
</DoubleAnimation>
</Storyboard>
</UserControl.Resources> <Grid x:Name="LayoutRoot" Background="#cccccc" Opacity="0.9">
<Grid.Resources>
<Storyboard x:Name="fadeImgStoryboard">
<DoubleAnimation x:Name="fadeImgAnimation" BeginTime="00:00:00" Storyboard.TargetName="LoadImg" Storyboard.TargetProperty="Opacity" From="1" To="0" Duration="0:0:01">
</DoubleAnimation>
</Storyboard>
</Grid.Resources>
<Image x:Name="LoadImg" Source="/SilverlightBusy;component/Images/Loading.png" Width="128" Height="128">
</Image>
<TextBlock x:Name="txtLoading" Width="60" VerticalAlignment="Center" HorizontalAlignment="Center" Text="Loading..."/>
</Grid>
</UserControl>

其实这个页面很简单,就是一个Grid、一个Image和一个TextBlock,添加两个Storyboard是为了有个过渡效果,这样看起来更加平滑一下,直接隐藏掉Image和TextBlock的话,会让人感觉闪一下。其设计视图如图:

其后台代码如下:

public partial class Load : UserControl
{
private int _counter = ;
private DispatcherTimer timer = new DispatcherTimer();
private RotateTransform rt = new RotateTransform();
private bool _isBusy = false;
public bool IsBusy
{
get
{
return _isBusy;
}
set
{
_isBusy = value;
if (value)
{
this.LayoutRoot.Visibility = Visibility.Visible;
this.LayoutRoot.Opacity = 0.9;
timer.Start();
}
else
{
//首先隐藏图片,图片隐藏后隐藏掉透明的背景层。
fadeImgStoryboard.Begin();
fadeImgStoryboard.Completed += (sender, e) =>
{
txtLoading.Visibility = Visibility.Collapsed;
fadeStoryboard.Begin();
};
fadeStoryboard.Completed += (sender, e) =>
{
timer.Stop();
this.LayoutRoot.Visibility = Visibility.Collapsed;
};
}
}
} public Load()
{
InitializeComponent();
timer.Interval = new TimeSpan();
timer.Tick += new EventHandler(timer_Tick);
timer.Start();
} void timer_Tick(object sender, EventArgs e)
{
_counter++;
//设置旋转中心点,根据图片大小设置,值为图片尺寸/2.
rt.CenterX = ;
rt.CenterY = ;
rt.Angle -= ; //旋转图片,每次旋转10度,可自定义旋转方向
LoadImg.RenderTransform = rt; //让Loading后面的点闪的不要太快
if (_counter % == )
{
if (txtLoading.Text.Equals("Loading..."))
{
txtLoading.Text = "Loading.";
}
else if (txtLoading.Text.Equals("Loading."))
{
txtLoading.Text = "Loading..";
}
else if (txtLoading.Text.Equals("Loading.."))
{
txtLoading.Text = "Loading...";
}
}
}
}

后台代码主要控制图片旋转动画和问题动画,还有就是数据加载完毕时,隐藏页面元素。

 三、在页面中调用

在MainPage中添加一个按钮,添加click事件,代码如下:

public partial class MainPage : UserControl
{
private Load load = null;
public MainPage()
{
InitializeComponent();
} private void button1_Click(object sender, RoutedEventArgs e)
{
load = new Load();
LayoutRoot.Children.Add(load);//将Load添加到页面,会显示在最顶层
load.IsBusy = true;
//在线程中调用,否则会造成UI线程阻塞。
new System.Threading.Thread(() =>
{
for (int i = ; i < ; i++)
{
System.Threading.Thread.Sleep();
}
this.Dispatcher.BeginInvoke(() =>
{
load.IsBusy = false;
});
}).Start();
}
}

添加完成后按F5执行,我们在打开的页面中单击按钮,就可以看到效果了。

当然,这里只是实现了和BusyIndicator一样的效果,如果想像使用BusyIndicator那样的话,我们还要进一步的进行封装。

点击下载源码

作者:雲霏霏

QQ交流群:243633526

博客地址:http://www.cnblogs.com/yunfeifei/

声明:本博客原创文字只代表本人工作中在某一时间内总结的观点或结论,与本人所在单位没有直接利益关系。非商业,未授权,贴子请以现状保留,转载时必须保留此段声明,且在文章页面明显位置给出原文连接。

如果大家感觉我的博文对大家有帮助,请推荐支持一把,给我写作的动力。

Silverlight及WPF中实现自定义BusyIndicator的更多相关文章

  1. WPF中实现自定义虚拟容器(实现VirtualizingPanel)

    WPF中实现自定义虚拟容器(实现VirtualizingPanel) 在WPF应用程序开发过程中,大数据量的数据展现通常都要考虑性能问题.有下面一种常见的情况:原始数据源数据量很大,但是某一时刻数据容 ...

  2. Silverlight和WPF中DataContractJsonSerializer对时间的处理差异

    原创文章转载请注明出处:@协思, http://zeeman.cnblogs.com Silverlight脱胎于WPF,他们的行为不完全并不完全相同,DataContractJsonSerializ ...

  3. C#、WPF中如何自定义鼠标样式

    需求:在C#中如何自定义鼠标样式?在这里可以分两种情况,一种是在winForm,另一种是在WPF中(注意使用的Cursor对象不一样) 解决办法如下: a.首先针对WinForm中,我们可以采用图标加 ...

  4. WPF中DATAGRID自定义验证(包含BINDINGGROUP)

    DataGrid在Wpf中的应用是十分广泛的,当你需要表中的信息稍详细的显示出来时,或者我们需要进行某些数据输入时,都有可能采用DataGrid.当然对信息的显示,我们不需要进行验证,但当我们将Dat ...

  5. WPF中如何使用BusyIndicator

    一.下载dll:http://wpftoolkit.codeplex.com/releases/view/99072 下载之后将WPFToolkit引用到WPF项目下: 二.添加命名空间: xmlns ...

  6. WPF中DataGrid自定义实现最后一行下面跟一个汇总行,类似MT4

    1.先看MT4实现的效果:(图中红框部分),其实就是DataGrid在最后一行下面跟一个汇总的显示条 2.看我WPF实现的效果,汇总行中的数据可以绑定哦!效果图如下: 我扩展了一下DataGrid控件 ...

  7. silverlight和wpf中暴露 给子类override

    protected virtual void OnSelectionChanged(SelectionChangedEventArgs args) { } public TestTabControl( ...

  8. 扩展ArcGIS API for Silverlight/WPF 中的TextSymbol支持角度标注

    原文 http://blog.csdn.net/esricd/article/details/7587136 在ArcGIS API for Silverlight/WPF中原版的TextSymbol ...

  9. 在WPF中自定义你的绘制(五)

    原文:在WPF中自定义你的绘制(五) 在WPF中自定义你的绘制(五)                                                                   ...

随机推荐

  1. JAVA基础(一)

    1.Java class中的static修饰的成员表面其属于该类所共有,而不是属于某个实例.static修饰的成员不能直接调用非static修饰的成员. 2.Java构造器不能定义返回类型,也不能使用 ...

  2. 解决C# WinForm Graphics绘制闪烁问题

    不直接使用form的CreateGraphics创建Graphics进行绘制,可以先在Form上面放一个需要大小的PictureBox,再创建一个同大小的Bitmap,将这个Bitmap设置为Pict ...

  3. 【powerdesigner】将pdm或者cdm保存为普通图片格式

    1.首先全选或者选择你要保存的元素[Ctrl+A] 2.Edit---->Export  Image

  4. Eclipse导入到最新版Android Studio详解

    说到使用AndroidStudio,除了新建的项目,我们都会面临的问题是原先Eclipse的代码该怎么导入到AndroidStudio中使用.这方面相关的资料还比较少,自己摸索了一下,总结出这篇博客, ...

  5. hellocharts包的使用心得

    首先将jar包导入Libs里面然后add进入于activity中调用 xml中加入布局 <lecho.lib.hellocharts.view.LineChartView android:id= ...

  6. 转:MYSQL连接字符串参数解析(解释)

    被迫转到MySQL数据库,发现读取数据库时,tinyint类型的值都被转化为boolean了,这样大于1的值都丢失,变成true了.查阅资料MySQL中无Boolean类型,都是存储为tinyint了 ...

  7. iOS路径沙盒文件管理(转载)

    iOS路径沙盒文件管理,看到博主总结的很好,转载过来,原文:http://www.aichengxu.com/view/35264 一.iOS中的沙盒机制 iOS应用程序只能对自己创建的文件系统读取文 ...

  8. GridView中实现DropDownList联动

    using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.We ...

  9. iOS 链式编程探索(Masonry)

    看了几篇关于链式编程的文章,还是理解的不透彻,我想这可能是因为我自己对block掌握的不熟练. 我已经明白了,所以,和大家分享一下我的理解!如有问题,麻烦大家指出! 直接看代码吧!关键的注释都有. 我 ...

  10. JAVA集合类型详解

    一.前言 作为java面试的常客[集合类型]是永恒的话题:在开发中,主要了解具体的使用,没有太多的去关注具体的理论说明,掌握那几种常用的集合类型貌似也就够使用了:导致这一些集合类型的理论有可能经常的忘 ...