在SnipperImages中使用了CheckBox控制,但它未直接使用Silverlight中的CheckBox,而是实现了
自己的CheckBox控件。当然它的实现方式是采用“控件复合”的方式(下面会详细说明)。而通过这种实现
方式,可以施加更多的控制和动画效果在CheckBox上,使其整体表现更酷(甚至定义第三种选中状态)。
当然,我们也可以通过VisualStateManager来订制 Silverlight所提供的CheckBox效果,例如下面的
视频教程:
http://silverlight.net/learn/learnvideo.aspx?video=56930
但我想写这个DEMO的人肯定是有其目的,我猜其意图是告诉我们如何进行控件的UI(xaml)绘制和事件
设计。说实在的,在看其CheckBox代码之前,我还真没想过如何去实现CheckBox,一是因为是简单,二
是它太基础了。不用我们去开发它,微软已把它变成“原子级”的控件封装到控制库中了。所以看到DEMO之
后,才让我感到控件设计也应该从原始做起,一步一步来构造行为越来越复杂,UI越来越酷的控件。
好了,开始今天的正文吧:)
在SnipperImages中,CheckBox由三个部件(所谓的部件(Parts)是指在空间模板中元素,控件逻辑
将会控制这些部件来完成一些特定的控件)组成:
Rectangle:用于绘制CheckBox外方框
Path:用于绘制选中时的"X"图形(当然也可以按自己的意愿任意绘制)
TextBlock:用于显示文本(提示)
这三个对象通过Grid.ColumnDefinitions进行布局,其中Rectangle和Path被放在一列,TextBlock一列。
如下Xaml代码所示:
<
ControlTemplate
xmlns
="http://schemas.microsoft.com/client/2007"
xmlns:x
="http://schemas.microsoft.com/winfx/2006/xaml"
>
<
Grid
x:Name
="Part_Root"
Width
="130"
Height
="30"
Background
="Transparent"
>
<
Grid.ColumnDefinitions
>
<
ColumnDefinition
Width
="30"
/>
<
ColumnDefinition
Width
="*"
/>
</
Grid.ColumnDefinitions
>
<
Rectangle
x:Name
="Part_Box"
Grid.Column
="0"
Width
='18'
Height
='18'
Stroke
='AliceBlue'
Margin
='2'
Fill
='Transparent'
/>
<
Path
x:Name
="Part_Check"
Grid.Column
="0"
Visibility
="Collapsed"
Stroke
='LightGreen'
StrokeThickness
='3'
IsHitTestVisible
='False'
Data
='M10,10 L20,20 M20,10 L10,20'
/>
<
TextBlock
x:Name
="Part_Text"
Grid.Column
="1"
Margin
="0,5,0,0"
Foreground
='Red'
FontSize
='12'
Text
='CheckBox'
/>
</
Grid
>
</
ControlTemplate
>
因为通常CheckBox在显示时为未放中状态,所以上面的Part_Check的Visibility属性为"Collapsed",而
在选中时为“Visible”。
而其显示效果如下图所示(红框内容对应上面的三个元素):
下面即是其控件的CS代码(详情见注释):
[TemplatePart(Name
=
"
Part_Root
"
, Type
=
typeof
(Panel))]
[TemplatePart(Name
=
"
Part_Box
"
, Type
=
typeof
(FrameworkElement))]
[TemplatePart(Name
=
"
Part_Check
"
, Type
=
typeof
(FrameworkElement))]
[TemplatePart(Name
=
"
Part_Text
"
, Type
=
typeof
(TextBlock))]
public
partial
class
CheckBox : Control
{
public
CheckBox()
{
string
xaml
=
ResourceHelper.GetTemplate(
this
.GetType());
ControlTemplate template
=
(ControlTemplate)XamlReader.Load(xaml);
this
.Template
=
template;
this
.ApplyTemplate();
}
///
<summary>
///
绑定模板元素及相应事件
///
</summary>
public
override
void
OnApplyTemplate()
{
Part_Root
=
(Panel)GetTemplateChild(
"
Part_Root
"
);
Part_Box
=
(FrameworkElement)GetTemplateChild(
"
Part_Box
"
);
Part_Check
=
(FrameworkElement)GetTemplateChild(
"
Part_Check
"
);
Part_Text
=
(TextBlock)GetTemplateChild(
"
Part_Text
"
);
Part_Box.MouseLeftButtonUp
+=
new
MouseButtonEventHandler(Part_Box_MouseLeftButtonUp);
}
#region
定义Check事件
public
event
EventHandler CheckedChanged;
protected
void
OnCheckedChanged()
{
if
(CheckedChanged
!=
null
)
{
CheckedChanged(
this
,
new
EventArgs());
}
}
#endregion
///
<summary>
///
Check元素鼠标左键Up事件
///
</summary>
///
<param name="sender"></param>
///
<param name="e"></param>
void
Part_Box_MouseLeftButtonUp(
object
sender, MouseButtonEventArgs e)
{
if
(_isChecked)
//
当在点选状态下点击时,则修改为“未选”状态
{
_isChecked
=
false
;
Part_Check.Visibility
=
Visibility.Collapsed;
//
让选中图标"X"为"不显示"
OnCheckedChanged();
//
运行绑定的客户端事件
}
else
//
与上面操作相反
{
_isChecked
=
true
;
Part_Check.Visibility
=
Visibility.Visible;
OnCheckedChanged();
}
}
private
bool
_isChecked
=
false
;
///
<summary>
///
当前控件的“选中”状态
///
</summary>
public
bool
IsChecked
{
get
{
return
_isChecked; }
set
{
_isChecked
=
value;
if
(_isChecked)
{
Part_Check.Visibility
=
Visibility.Visible;
}
else
{
Part_Check.Visibility
=
Visibility.Collapsed;
}
}
}
///
<summary>
///
Checkbox文本
///
</summary>
public
string
Text
{
get
{
return
Part_Text.Text; }
set
{ Part_Text.Text
=
value; }
}
#region
UI元素定义
private
Panel Part_Root;
private
FrameworkElement Part_Box;
private
FrameworkElement Part_Check;
private
TextBlock Part_Text;
#endregion
}
下面是一个使用DEMO,首先是Xaml中的定义:
<
ctl:CheckBox
x:Name
="cbFullscreen"
Text
="(全屏)复选
框"
CheckedChanged
="
OnFullscreenCheckedChanged"
/>
接着是实现全屏复选框所执行的CS代码:
public
Page2()
{
InitializeComponent();
//
绑定全屏状态触发事件
App.Current.Host.Content.FullScreenChanged
+=
new
EventHandler(Content_FullScreenChanged);
}
#region
CheckBox示例代码
void
OnFullscreenCheckedChanged(
object
sender, EventArgs e)
{
App.Current.Host.Content.IsFullScreen
=
cbFullscreen.IsChecked;
}
void
Content_FullScreenChanged(
object
sender, EventArgs e)
{
if
(App.Current.Host.Content.IsFullScreen
==
true
)
{
cbFullscreen.IsChecked
=
true
;
}
else
{
cbFullscreen.IsChecked
=
false
;
}
}
#endregion
好了,今天的内容就先到这里了:)
tag:Silverlight,ImageSnipper,checkbox,控件开发
作者:代震军,daizhj
原文链接:http://www.cnblogs.com/daizhj/archive/2008/09/03/1282819.html
源码下载,请点击这里:)