这里将要介绍一个最简单的幻灯片程序,可以应用在Banner广告或图片播放。图片通过XML传递,配置非常方便。(实例源码下载)
在这篇文章的代码里,我将配与非常详细的注释,希望能通过代码说明SL的一些问题。
那么就开始吧,先看看效果图:

首先分析下界面的元素结构:
有按钮、半透明的按钮容器、图片控件
东西不多,先从按钮说起:
在工程里创建一个UserControl,命名为TiggerButton,并在XAML中写下如下代码:
然后的Rectangle就是我们看见的矩形框,框四角的圆角,是由RadiusX和RadiusY指定的。StrokeThickness指定的是边框的宽度。
TextBlock的作用和我们在Winform里遇见的Label非常相似,用于输出字符串。而且Alignment属性也非常好用,直接就指定了该控件的位置,在这里由于没有指定按钮的文字,所以使用了垂直、水平居中。
上面代码中,最外层的Grid是自动生成的,它的作用是使得该控件中可以包含多个子元素,因为Grid继承Panel,默认属性是Children,所以可以直接把UIElement放入Grid中。在Grid中注册了MouseEnter和MouseLeave事件,这里的处理方法和Winform,ASP.NET是同出一辄的。
TiggerButton 后台代码
public partial class TiggerButton : UserControl
{
//依赖属性
public static readonly DependencyProperty NumberProperty = DependencyProperty.Register("Number",
typeof(int),
typeof(TiggerButton),
new PropertyMetadata(1));
public ADEntity ADE
{
get; set;
}
/**////
/// 在按钮上显示的数字
///
public int Number
{
get
{
return (int) GetValue(NumberProperty);
}
set
{
SetValue(NumberProperty,value);
tb_Number.Text = value.ToString();
}
}
/**////
/// 构造函数
///
public TiggerButton(int number,ADEntity ade):this(number)
{
ADE = ade;
}
/**////
/// 构造函数
///
public TiggerButton(int number):this()
{
Number = number;
}
public TiggerButton()
{
InitializeComponent();
}
private void LayoutRoot_MouseEnter ( object sender, MouseEventArgs e )
{
//设置按钮背景透明度
BackGroundRec.Opacity = 0.5;
}
private void LayoutRoot_MouseLeave ( object sender, MouseEventArgs e )
{
BackGroundRec.Opacity = 1;
}
/**////
/// 按钮被点击后触发
///
public event EventHandler onSelected;
private void UserControl_MouseLeftButtonDown ( object sender, MouseButtonEventArgs e )
{
if(onSelected!=null)
{
onSelected(this, null);
}
}
}另外,在整个用户控件里,我还注册了MouseLeftButtonDown事件,并在这个事件里转发我声明的选中事件。
按钮就这样完成了。
然后在工程里创建另一个用户控件:AD,并在XAML中写下如下代码:
以上代码中,Grid的MouseEnter事件和MouseLeave事件里把矩形框的不透明度设置为0.5和1,以提示按钮被选中。
AD XAML
上面的XAML中,描述了幻灯片的工作原理(两个图片控件不停变换透明装,并替换不同的图片),在按钮容器部分,我使用了StackPanel,就不需要对按钮的布局进行更多的控制了。
AD 后台代码
public partial class AD : UserControl
{
/**////
/// 幻灯片计时器
///
DispatcherTimer timer;
/**////
/// 记录当前显示的AD
///
public ADEntity currentAD;
/**////
/// 记录当前正在使用的Image
///
Image currentImage;
/**////
/// 当前正在显示的AD
///
public ADEntity CurrentAD
{
get
{
return currentAD;
}
set
{
//外界可通过更改值,并显示替换图片的动态效果
if(!currentAD.Equals(value))
{
currentAD = value;
BeginAnim(value);
}
}
}
/**////
/// AD列表
///
List
/**////
/// 构造方法
///
public AD ( List
: this ()
{
ads = ADs;
}
public AD()
{
InitializeComponent();
//初始化计时器
timer=new DispatcherTimer();
//计时器间隔5秒
timer.Interval = new TimeSpan(0,0,0,5);
timer.Tick += timer_Tick;
timer.Start ();
}
void timer_Tick ( object sender, EventArgs e )
{
for(int i=0;i
{
if(currentAD.Equals(ads[i]))
{
//在计时器中循环替换当前AD
CurrentAD = i==ads.Count-1 ? ads[0] : ads[i + 1];
break;
}
}
}
private void UserControl_Loaded ( object sender, RoutedEventArgs e )
{
for(int i=0;i
{
//加载按钮
TiggerButton tb = new TiggerButton(i + 1, ads[i]);
//按钮样式,边距为5
tb.Margin=new Thickness(5);
tb.onSelected += tb_onSelected;
ButtonContainer.Children.Add(tb);
}
if ( ads.Count > 0 )
{
//为当前AD赋初始值
currentAD = ads[0];
Image1.Source = new BitmapImage(new Uri(currentAD.Image, UriKind.Relative));
currentImage = Image1;
}
}
void tb_onSelected ( object sender, EventArgs e )
{
//按钮被选中后,替换当前AD
CurrentAD = ((TiggerButton) sender).ADE;
//重设计时器
timer.Start();
}
/**////
/// 播放动画
///
public void BeginAnim(ADEntity adEntity)
{
//构造新故事版
Storyboard sb_Opacity = new Storyboard();
//图片隐藏动画
DoubleAnimation ImageHideAnim = new DoubleAnimation
{
//透明度目标为0
To = 0,
//1秒动画时间
Duration = new TimeSpan(0, 0, 1)
};
//图片显示动画
DoubleAnimation ImageShowAnim = new DoubleAnimation
{
//透明度目标为1
To = 1,
//透明度初始值为0
From=0,
Duration = new TimeSpan(0, 0, 1)
};
//构造图片URI
Uri uri = new Uri(adEntity.Image, UriKind.Relative);
if(currentImage==Image1)
{
//为新图片赋值
Image2.Source = new BitmapImage(uri);
ImageHideAnim.From = Image1.Opacity;
//设置动画对象
Storyboard.SetTarget(ImageHideAnim, Image1);
Storyboard.SetTarget(ImageShowAnim, Image2);
//设置当前Image
currentImage = Image2;
}
else if (currentImage==Image2)
{
Image1.Source = new BitmapImage(uri);
ImageHideAnim.From = Image2.Opacity;
Storyboard.SetTarget(ImageHideAnim,Image2);
Storyboard.SetTarget(ImageShowAnim,Image1);
currentImage = Image1;
}
//设置动画对象属性
Storyboard.SetTargetProperty ( ImageHideAnim, new PropertyPath ( "Opacity" ) );
Storyboard.SetTargetProperty ( ImageShowAnim, new PropertyPath ( "Opacity" ) );
//把动画添加到故事版中
sb_Opacity.Children.Add(ImageHideAnim);
sb_Opacity.Children.Add(ImageShowAnim);
//开始动画
sb_Opacity.Begin();
}
private void UserControl_MouseEnter ( object sender, System.Windows.Input.MouseEventArgs e )
{
Storyboard sb = new Storyboard();
DoubleAnimation da = new DoubleAnimation()
{
Duration = new TimeSpan(0,0,1),
To = 1,
From = ContainerGrid.Opacity
};
Storyboard.SetTarget(da, ContainerGrid);
Storyboard.SetTargetProperty(da, new PropertyPath("Opacity"));
sb.Children.Add(da);
sb.Begin();
}
private void UserControl_MouseLeave ( object sender, System.Windows.Input.MouseEventArgs e )
{
Storyboard sb = new Storyboard();
DoubleAnimation da = new DoubleAnimation
{
Duration = new TimeSpan(0,0,1),
To = 0,
From = ContainerGrid.Opacity
};
Storyboard.SetTarget(da, ContainerGrid);
Storyboard.SetTargetProperty(da, new PropertyPath("Opacity"));
sb.Children.Add(da);
sb.Begin();
}
}在播放动画的方法中,构造了个故事版,并把TimeLine对象添加进去。
在SL的动画中,有很多类型的TimeLine,这些TimeLine可以指定不同数据类型的变化动画。
在SetTargetProperty方法中,设置的必须是依赖属性。并且这个依赖属性必须是在后台声明的名称,类似
依赖属性
public static readonly DependencyProperty NumberProperty = DependencyProperty.Register("Number",
typeof(int),
typeof(TiggerButton),
new PropertyMetadata(1));中的Number这个字符串。
XML的读取我就不再赘言了,不过要说明的是SL的运行环境中的XML对象模型,和普通的Framework对象模型完全不同,再也不能用XMLDocument之类的对象了。