本文所要介绍的Slider控件在xaml上与CheckBox复杂度相似,比较底。而控件逻辑相对要复杂不少,这些
逻辑会在本文中进行介绍。
好了,开始今天的正文。
首先看一下这个演示页,如下:
注:因为我从网上所获得的源码中Slider控件并没有全部开发完,起码在上面所示的垂直Slider只是粗
略的定义了xaml(其中某些值还有错误),而CS代码就少得更多了。本人在原有代码基础上,完成了垂直
Slider的开发,并修正了原有的CS代码中的BUG。
而该控件的xaml代码如下所示(Slider.xaml):
<
ControlTemplate
xmlns
="http://schemas.microsoft.com/client/2007"
xmlns:x ="http://schemas.microsoft.com/winfx/2006/xaml" >
< Grid x:Name ="Part_Root" Width ="200" Height ="24" >
< Canvas x:Name ="Part_Border" Background ="Transparent" >
< Line x:Name ='Part_Line' StrokeThickness ="1" Stroke ="Blue" X1 ="4" X2 ="196" Y1 ="12"
Y2 ="12" />
< Path x:Name ='Part_ThumbHorizontal' Canvas.Top ='3' Data ='M0,0 L16,0 L8,18z' Fill ='Silver'
Stroke ='Black' />
< Path x:Name ='Part_ThumbVertical' Canvas.Left ='3' Visibility ="Collapsed"
Data ='M0,0 L18,8 L0,16z' Fill ='Silver' Stroke ='Black' />
</ Canvas >
</ Grid >
</ ControlTemplate >
xmlns:x ="http://schemas.microsoft.com/winfx/2006/xaml" >
< Grid x:Name ="Part_Root" Width ="200" Height ="24" >
< Canvas x:Name ="Part_Border" Background ="Transparent" >
< Line x:Name ='Part_Line' StrokeThickness ="1" Stroke ="Blue" X1 ="4" X2 ="196" Y1 ="12"
Y2 ="12" />
< Path x:Name ='Part_ThumbHorizontal' Canvas.Top ='3' Data ='M0,0 L16,0 L8,18z' Fill ='Silver'
Stroke ='Black' />
< Path x:Name ='Part_ThumbVertical' Canvas.Left ='3' Visibility ="Collapsed"
Data ='M0,0 L18,8 L0,16z' Fill ='Silver' Stroke ='Black' />
</ Canvas >
</ Grid >
</ ControlTemplate >
从上面代码可以看出,Slider由四个主要元素组成:
Part_Border:用于绘制背景色(如ColorSlider控件的背景色)
Part_Line:用于绘制滑动的中线
Part_ThumbHorizontal:用于绘制水平滑块
Part_ThumbVertical:用于绘制垂直滑块
Part_Line:用于绘制滑动的中线
Part_ThumbHorizontal:用于绘制水平滑块
Part_ThumbVertical:用于绘制垂直滑块
下面这张图标识了各元素在控件中的对应位置和关系:
对应上图,下面是ColorSlider的xaml代码:
<
ControlTemplate
xmlns
="http://schemas.microsoft.com/client/2007"
xmlns:x ="http://schemas.microsoft.com/winfx/2006/xaml" >
< Grid x:Name ="Part_Root" Width ='200' Height ='24' >
< Canvas x:Name ='Part_Border' >
< Canvas.Background >
< LinearGradientBrush x:Name ="GradientBrush" StartPoint ="0,0" EndPoint ="1,0" >
< GradientStop Color ="#FF000000" Offset ="0" />
< GradientStop Color ="#FFFF0000" Offset ="0.143" />
< GradientStop Color ="#FF00FF00" Offset ="0.286" />
< GradientStop Color ="#FF0000FF" Offset ="0.429" />
< GradientStop Color ="#FF00FFFF" Offset ="0.571" />
< GradientStop Color ="#FFFF00FF" Offset ="0.714" />
< GradientStop Color ="#FFFFFF00" Offset ="0.857" />
< GradientStop Color ="#FFFFFFFF" Offset ="1" />
</ LinearGradientBrush >
</ Canvas.Background >
< Line x:Name ='Part_Line' StrokeThickness ="1" Stroke ="Blue" X1 ="4" X2 ="196" Y1 ="12" Y2 ="12" />
< Path x:Name ='Part_ThumbHorizontal' Canvas.Top ='3' Data ='M0,0 L16,0 L8,18z' Fill ='Silver'
Stroke ='Black' />
< Path x:Name ='Part_ThumbVertical' Canvas.Left ='3' Visibility ="Collapsed"
Data ='M0,0 L18,8 L0,16z' Fill ='Silver' Stroke ='Black' />
</ Canvas >
</ Grid >
</ ControlTemplate >
xmlns:x ="http://schemas.microsoft.com/winfx/2006/xaml" >
< Grid x:Name ="Part_Root" Width ='200' Height ='24' >
< Canvas x:Name ='Part_Border' >
< Canvas.Background >
< LinearGradientBrush x:Name ="GradientBrush" StartPoint ="0,0" EndPoint ="1,0" >
< GradientStop Color ="#FF000000" Offset ="0" />
< GradientStop Color ="#FFFF0000" Offset ="0.143" />
< GradientStop Color ="#FF00FF00" Offset ="0.286" />
< GradientStop Color ="#FF0000FF" Offset ="0.429" />
< GradientStop Color ="#FF00FFFF" Offset ="0.571" />
< GradientStop Color ="#FFFF00FF" Offset ="0.714" />
< GradientStop Color ="#FFFFFF00" Offset ="0.857" />
< GradientStop Color ="#FFFFFFFF" Offset ="1" />
</ LinearGradientBrush >
</ Canvas.Background >
< Line x:Name ='Part_Line' StrokeThickness ="1" Stroke ="Blue" X1 ="4" X2 ="196" Y1 ="12" Y2 ="12" />
< Path x:Name ='Part_ThumbHorizontal' Canvas.Top ='3' Data ='M0,0 L16,0 L8,18z' Fill ='Silver'
Stroke ='Black' />
< Path x:Name ='Part_ThumbVertical' Canvas.Left ='3' Visibility ="Collapsed"
Data ='M0,0 L18,8 L0,16z' Fill ='Silver' Stroke ='Black' />
</ Canvas >
</ Grid >
</ ControlTemplate >
说完了xaml,下面开始介绍cs控件逻辑代码。
首先要说的是一个枚举类型,用于标识滑动方向(垂直或水平):
///
<summary>
/// 滑动条方向类型
/// </summary>
public enum SliderOrientation
{
/// <summary>
/// 垂直
/// </summary>
Vertical,
/// <summary>
/// 水平
/// </summary>
Horizontal
}
/// 滑动条方向类型
/// </summary>
public enum SliderOrientation
{
/// <summary>
/// 垂直
/// </summary>
Vertical,
/// <summary>
/// 水平
/// </summary>
Horizontal
}
而控件的核心代码如下(有关我修改或添加的部分已通过注释说明):
///
<summary>
/// 滑动条控制类
/// </summary>
[TemplatePart(Name = " Part_Root " , Type = typeof (Panel))]
[TemplatePart(Name = " Part_Border " , Type = typeof (FrameworkElement))]
[TemplatePart(Name = " Part_ThumbHorizontal " , Type = typeof (FrameworkElement))]
[TemplatePart(Name = " Part_ThumbVertical " , Type = typeof (FrameworkElement))]
[TemplatePart(Name = " Part_Line " , Type = typeof (FrameworkElement))]
public partial class Slider : Control
{
public Slider()
{
string xaml = ResourceHelper.GetTemplate( this .GetType());
ControlTemplate template = (ControlTemplate)XamlReader.Load(xaml);
this .Template = template;
this .ApplyTemplate();
}
public event EventHandler ValueChanged;
/// <summary>
/// 值改变时
/// </summary>
protected void OnValueChanged()
{
if (ValueChanged != null )
{
// 执行绑定代码
ValueChanged( this , new EventArgs());
}
}
/// <summary>
/// 绑定模板元素及相应事件
/// </summary>
public override void OnApplyTemplate()
{
Part_Root = (Panel)GetTemplateChild( " Part_Root " );
Part_Line = (Line)GetTemplateChild( " Part_Line " );
Part_ThumbHorizontal = (FrameworkElement)GetTemplateChild( " Part_ThumbHorizontal " );
Part_ThumbVertical = (FrameworkElement)GetTemplateChild( " Part_ThumbVertical " );
Part_Border = (FrameworkElement)GetTemplateChild( " Part_Border " );
Part_ThumbHorizontal.MouseLeftButtonDown += new MouseButtonEventHandler(Part_Thumb_MouseLeftButtonDown);
Part_ThumbHorizontal.MouseMove += new MouseEventHandler(Part_Thumb_MouseMove);
Part_ThumbHorizontal.MouseLeftButtonUp += new MouseButtonEventHandler(Part_Thumb_MouseLeftButtonUp);
Part_ThumbVertical.MouseLeftButtonDown += new MouseButtonEventHandler(Part_Thumb_MouseLeftButtonDown);
Part_ThumbVertical.MouseMove += new MouseEventHandler(Part_Thumb_MouseMove);
Part_ThumbVertical.MouseLeftButtonUp += new MouseButtonEventHandler(Part_Thumb_MouseLeftButtonUp);
Part_Root.MouseLeave += new MouseEventHandler(Part_Root_MouseLeave);
Part_Root.MouseEnter += new MouseEventHandler(Part_Root_MouseEnter);
Part_Border.MouseLeftButtonDown += new MouseButtonEventHandler(Part_Border_MouseLeftButtonDown);
}
/// <summary>
/// 当鼠标在滑动条(不是滑块)上点击时,将滑块设置到鼠标点击位置
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void Part_Border_MouseLeftButtonDown( object sender, MouseButtonEventArgs e)
{
// 当不是滑块时
if (e.Source != Part_ThumbHorizontal && e.Source != Part_ThumbVertical)
{
Point newPos = e.GetPosition(Part_Root);
{
if (_orientation == SliderOrientation.Horizontal)
{
Part_ThumbHorizontal.SetValue(Canvas.LeftProperty, Math.Min(newPos.X,
Part_Border.ActualWidth - Part_ThumbHorizontal.ActualWidth));
}
else
{
Part_ThumbVertical.SetValue(Canvas.TopProperty, Math.Min(newPos.Y,
Part_Border.ActualHeight - Part_ThumbVertical.ActualHeight));
}
this .OnValueChanged();
}
}
}
/// <summary>
/// 鼠标进入滑动条区域
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void Part_Root_MouseEnter( object sender, MouseEventArgs e)
{
if (hasCapture)
{
if (_orientation == SliderOrientation.Horizontal)
{
Part_ThumbHorizontal.CaptureMouse();
}
else
{
Part_ThumbVertical.CaptureMouse();
}
}
else
{
_mouseDownValue = - 1 ;
}
}
/// <summary>
/// 鼠标离开滑动条区域
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void Part_Root_MouseLeave( object sender, MouseEventArgs e)
{
if (_orientation == SliderOrientation.Horizontal)
{
Part_ThumbHorizontal.ReleaseMouseCapture();
}
else
{
Part_ThumbVertical.ReleaseMouseCapture();
}
}
/// <summary>
/// 鼠标按下滑动块
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void Part_Thumb_MouseLeftButtonDown( object sender, MouseButtonEventArgs e)
{
FrameworkElement thumb = (FrameworkElement)sender;
// 在当前滑动块上设置“鼠标捕获”
thumb.CaptureMouse();
hasCapture = true ;
_thumbMouseDown = e.GetPosition(Part_Root);
if (_orientation == SliderOrientation.Horizontal) // 当为水平方向时
{
// 获取滑动块的“左”值属性
_mouseDownValue = ( double )thumb.GetValue(Canvas.LeftProperty);
}
else
{
// 获取滑动块的“顶”值属性
_mouseDownValue = ( double )thumb.GetValue(Canvas.TopProperty);
}
}
/// <summary>
/// 鼠标拖动滑动块移动
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void Part_Thumb_MouseMove( object sender, MouseEventArgs e)
{
FrameworkElement thumb = (FrameworkElement)sender;
Point newPos = e.GetPosition(Part_Root);
if (_orientation == SliderOrientation.Horizontal)
{
double newX = newPos.X - _thumbMouseDown.X + _mouseDownValue;
if (_mouseDownValue != - 1 &&
newX <= Part_Border.ActualWidth - 8 &&
newX >= - 8 )
{
thumb.SetValue(Canvas.LeftProperty, newX); // 仅在水平方向上移动
this .OnValueChanged();
}
}
else
{
double newY = newPos.Y - _thumbMouseDown.Y + _mouseDownValue;
if (_mouseDownValue != - 1 &&
newY <= Part_Border.ActualHeight - 8 &&
newY >= - 8 )
{
thumb.SetValue(Canvas.TopProperty, newY); // 仅在垂直方向上移动
this .OnValueChanged();
}
}
}
/// <summary>
/// 鼠标拖动结束
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void Part_Thumb_MouseLeftButtonUp( object sender, MouseButtonEventArgs e)
{
FrameworkElement thumb = (FrameworkElement)sender;
_mouseDownValue = - 1 ;
thumb.ReleaseMouseCapture();
hasCapture = false ;
}
/// <summary>
/// 设置滑动条的宽
/// </summary>
public double SliderWidth
{
get { return Part_Root.Width; }
set
{
if (_orientation == SliderOrientation.Horizontal)
{
// 水平方向上设置
Part_Line.X2 = value;
Part_Root.Width = value;
}
else
{
// 获取Slider.xaml中的相应属性配置
Part_Line.X1 = Part_Line.X2 = value / 2d;
Part_ThumbVertical.SetValue(Canvas.LeftProperty, value / 2d - Part_ThumbVertical.ActualWidth / 2d);
}
}
}
/// <summary>
/// 设置滑动条的高度
/// </summary>
public double SliderHeight
{
get { return Part_Root.Height; }
set
{
if (_orientation == SliderOrientation.Horizontal)
{
// 获取Slider.xaml中的相应属性配置
Part_Line.Y1 = Part_Line.Y2 = value / 2d;
Part_ThumbHorizontal.SetValue(Canvas.TopProperty, value / 2d - Part_ThumbHorizontal.ActualHeight / 2d);
}
else
{
// 垂直方向上设置
Part_Line.Y2 = value;
Part_Root.Height = value;
}
}
}
/// <summary>
/// 获取或设置滑动条的当前值
/// </summary>
public double Value
{
get
{
if (_orientation == SliderOrientation.Horizontal)
{
double val = ( double )Part_ThumbHorizontal.GetValue(Canvas.LeftProperty) / (Part_Root.ActualWidth - 8 );
val = Math.Max(0d, val);
val = Math.Min(val, 1d);
return val;
}
else
{
double val = ( double )Part_ThumbVertical.GetValue(Canvas.TopProperty) / (Part_Root.ActualHeight - 8 );
val = Math.Max(0d, val);
val = Math.Min(val, 1d);
return val;
}
}
set
{
if (_orientation == SliderOrientation.Horizontal)
{
Part_ThumbHorizontal.SetValue(Canvas.LeftProperty, value * (Part_Root.Width - 8 ));
}
else
{
Part_ThumbVertical.SetValue(Canvas.TopProperty, value * (Part_Root.Height - 8 ));
}
}
}
/// <summary>
/// 获取或设置滑动条的方向,参见SliderOrientation
/// </summary>
public SliderOrientation Orientation
{
get { return _orientation; }
set
{
_orientation = value;
if (_orientation == SliderOrientation.Horizontal)
{
Part_ThumbVertical.Visibility = Visibility.Collapsed;
Part_ThumbHorizontal.Visibility = Visibility.Visible;
Part_Line.Y1 = Part_Line.Y2 = Part_Root.Height / 2d;
Part_Line.X1 = 0d;
Part_Line.X2 = Part_Root.Width;
}
else
{
// 注:此处代码为本人所加,用于当为垂直方向时,交换Width与Height的值
double temp = Part_Root.Width;
Part_Root.Width = Part_Root.Height;
Part_Root.Height = temp;
Part_ThumbHorizontal.Visibility = Visibility.Collapsed;
Part_ThumbVertical.Visibility = Visibility.Visible;
Part_Line.X1 = Part_Line.X2 = Part_Root.Width / 2d;
Part_Line.Y1 = 0d;
Part_Line.Y2 = Part_Root.Height;
}
}
}
#region UI元素声明
protected Panel Part_Root;
protected Line Part_Line;
protected FrameworkElement Part_Border, Part_ThumbVertical, Part_ThumbHorizontal;
#endregion
protected Point _thumbMouseDown;
protected double _mouseDownValue = - 1 ;
protected bool hasCapture = false ;
protected SliderOrientation _orientation = SliderOrientation.Horizontal;
}
/// 滑动条控制类
/// </summary>
[TemplatePart(Name = " Part_Root " , Type = typeof (Panel))]
[TemplatePart(Name = " Part_Border " , Type = typeof (FrameworkElement))]
[TemplatePart(Name = " Part_ThumbHorizontal " , Type = typeof (FrameworkElement))]
[TemplatePart(Name = " Part_ThumbVertical " , Type = typeof (FrameworkElement))]
[TemplatePart(Name = " Part_Line " , Type = typeof (FrameworkElement))]
public partial class Slider : Control
{
public Slider()
{
string xaml = ResourceHelper.GetTemplate( this .GetType());
ControlTemplate template = (ControlTemplate)XamlReader.Load(xaml);
this .Template = template;
this .ApplyTemplate();
}
public event EventHandler ValueChanged;
/// <summary>
/// 值改变时
/// </summary>
protected void OnValueChanged()
{
if (ValueChanged != null )
{
// 执行绑定代码
ValueChanged( this , new EventArgs());
}
}
/// <summary>
/// 绑定模板元素及相应事件
/// </summary>
public override void OnApplyTemplate()
{
Part_Root = (Panel)GetTemplateChild( " Part_Root " );
Part_Line = (Line)GetTemplateChild( " Part_Line " );
Part_ThumbHorizontal = (FrameworkElement)GetTemplateChild( " Part_ThumbHorizontal " );
Part_ThumbVertical = (FrameworkElement)GetTemplateChild( " Part_ThumbVertical " );
Part_Border = (FrameworkElement)GetTemplateChild( " Part_Border " );
Part_ThumbHorizontal.MouseLeftButtonDown += new MouseButtonEventHandler(Part_Thumb_MouseLeftButtonDown);
Part_ThumbHorizontal.MouseMove += new MouseEventHandler(Part_Thumb_MouseMove);
Part_ThumbHorizontal.MouseLeftButtonUp += new MouseButtonEventHandler(Part_Thumb_MouseLeftButtonUp);
Part_ThumbVertical.MouseLeftButtonDown += new MouseButtonEventHandler(Part_Thumb_MouseLeftButtonDown);
Part_ThumbVertical.MouseMove += new MouseEventHandler(Part_Thumb_MouseMove);
Part_ThumbVertical.MouseLeftButtonUp += new MouseButtonEventHandler(Part_Thumb_MouseLeftButtonUp);
Part_Root.MouseLeave += new MouseEventHandler(Part_Root_MouseLeave);
Part_Root.MouseEnter += new MouseEventHandler(Part_Root_MouseEnter);
Part_Border.MouseLeftButtonDown += new MouseButtonEventHandler(Part_Border_MouseLeftButtonDown);
}
/// <summary>
/// 当鼠标在滑动条(不是滑块)上点击时,将滑块设置到鼠标点击位置
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void Part_Border_MouseLeftButtonDown( object sender, MouseButtonEventArgs e)
{
// 当不是滑块时
if (e.Source != Part_ThumbHorizontal && e.Source != Part_ThumbVertical)
{
Point newPos = e.GetPosition(Part_Root);
{
if (_orientation == SliderOrientation.Horizontal)
{
Part_ThumbHorizontal.SetValue(Canvas.LeftProperty, Math.Min(newPos.X,
Part_Border.ActualWidth - Part_ThumbHorizontal.ActualWidth));
}
else
{
Part_ThumbVertical.SetValue(Canvas.TopProperty, Math.Min(newPos.Y,
Part_Border.ActualHeight - Part_ThumbVertical.ActualHeight));
}
this .OnValueChanged();
}
}
}
/// <summary>
/// 鼠标进入滑动条区域
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void Part_Root_MouseEnter( object sender, MouseEventArgs e)
{
if (hasCapture)
{
if (_orientation == SliderOrientation.Horizontal)
{
Part_ThumbHorizontal.CaptureMouse();
}
else
{
Part_ThumbVertical.CaptureMouse();
}
}
else
{
_mouseDownValue = - 1 ;
}
}
/// <summary>
/// 鼠标离开滑动条区域
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void Part_Root_MouseLeave( object sender, MouseEventArgs e)
{
if (_orientation == SliderOrientation.Horizontal)
{
Part_ThumbHorizontal.ReleaseMouseCapture();
}
else
{
Part_ThumbVertical.ReleaseMouseCapture();
}
}
/// <summary>
/// 鼠标按下滑动块
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void Part_Thumb_MouseLeftButtonDown( object sender, MouseButtonEventArgs e)
{
FrameworkElement thumb = (FrameworkElement)sender;
// 在当前滑动块上设置“鼠标捕获”
thumb.CaptureMouse();
hasCapture = true ;
_thumbMouseDown = e.GetPosition(Part_Root);
if (_orientation == SliderOrientation.Horizontal) // 当为水平方向时
{
// 获取滑动块的“左”值属性
_mouseDownValue = ( double )thumb.GetValue(Canvas.LeftProperty);
}
else
{
// 获取滑动块的“顶”值属性
_mouseDownValue = ( double )thumb.GetValue(Canvas.TopProperty);
}
}
/// <summary>
/// 鼠标拖动滑动块移动
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void Part_Thumb_MouseMove( object sender, MouseEventArgs e)
{
FrameworkElement thumb = (FrameworkElement)sender;
Point newPos = e.GetPosition(Part_Root);
if (_orientation == SliderOrientation.Horizontal)
{
double newX = newPos.X - _thumbMouseDown.X + _mouseDownValue;
if (_mouseDownValue != - 1 &&
newX <= Part_Border.ActualWidth - 8 &&
newX >= - 8 )
{
thumb.SetValue(Canvas.LeftProperty, newX); // 仅在水平方向上移动
this .OnValueChanged();
}
}
else
{
double newY = newPos.Y - _thumbMouseDown.Y + _mouseDownValue;
if (_mouseDownValue != - 1 &&
newY <= Part_Border.ActualHeight - 8 &&
newY >= - 8 )
{
thumb.SetValue(Canvas.TopProperty, newY); // 仅在垂直方向上移动
this .OnValueChanged();
}
}
}
/// <summary>
/// 鼠标拖动结束
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void Part_Thumb_MouseLeftButtonUp( object sender, MouseButtonEventArgs e)
{
FrameworkElement thumb = (FrameworkElement)sender;
_mouseDownValue = - 1 ;
thumb.ReleaseMouseCapture();
hasCapture = false ;
}
/// <summary>
/// 设置滑动条的宽
/// </summary>
public double SliderWidth
{
get { return Part_Root.Width; }
set
{
if (_orientation == SliderOrientation.Horizontal)
{
// 水平方向上设置
Part_Line.X2 = value;
Part_Root.Width = value;
}
else
{
// 获取Slider.xaml中的相应属性配置
Part_Line.X1 = Part_Line.X2 = value / 2d;
Part_ThumbVertical.SetValue(Canvas.LeftProperty, value / 2d - Part_ThumbVertical.ActualWidth / 2d);
}
}
}
/// <summary>
/// 设置滑动条的高度
/// </summary>
public double SliderHeight
{
get { return Part_Root.Height; }
set
{
if (_orientation == SliderOrientation.Horizontal)
{
// 获取Slider.xaml中的相应属性配置
Part_Line.Y1 = Part_Line.Y2 = value / 2d;
Part_ThumbHorizontal.SetValue(Canvas.TopProperty, value / 2d - Part_ThumbHorizontal.ActualHeight / 2d);
}
else
{
// 垂直方向上设置
Part_Line.Y2 = value;
Part_Root.Height = value;
}
}
}
/// <summary>
/// 获取或设置滑动条的当前值
/// </summary>
public double Value
{
get
{
if (_orientation == SliderOrientation.Horizontal)
{
double val = ( double )Part_ThumbHorizontal.GetValue(Canvas.LeftProperty) / (Part_Root.ActualWidth - 8 );
val = Math.Max(0d, val);
val = Math.Min(val, 1d);
return val;
}
else
{
double val = ( double )Part_ThumbVertical.GetValue(Canvas.TopProperty) / (Part_Root.ActualHeight - 8 );
val = Math.Max(0d, val);
val = Math.Min(val, 1d);
return val;
}
}
set
{
if (_orientation == SliderOrientation.Horizontal)
{
Part_ThumbHorizontal.SetValue(Canvas.LeftProperty, value * (Part_Root.Width - 8 ));
}
else
{
Part_ThumbVertical.SetValue(Canvas.TopProperty, value * (Part_Root.Height - 8 ));
}
}
}
/// <summary>
/// 获取或设置滑动条的方向,参见SliderOrientation
/// </summary>
public SliderOrientation Orientation
{
get { return _orientation; }
set
{
_orientation = value;
if (_orientation == SliderOrientation.Horizontal)
{
Part_ThumbVertical.Visibility = Visibility.Collapsed;
Part_ThumbHorizontal.Visibility = Visibility.Visible;
Part_Line.Y1 = Part_Line.Y2 = Part_Root.Height / 2d;
Part_Line.X1 = 0d;
Part_Line.X2 = Part_Root.Width;
}
else
{
// 注:此处代码为本人所加,用于当为垂直方向时,交换Width与Height的值
double temp = Part_Root.Width;
Part_Root.Width = Part_Root.Height;
Part_Root.Height = temp;
Part_ThumbHorizontal.Visibility = Visibility.Collapsed;
Part_ThumbVertical.Visibility = Visibility.Visible;
Part_Line.X1 = Part_Line.X2 = Part_Root.Width / 2d;
Part_Line.Y1 = 0d;
Part_Line.Y2 = Part_Root.Height;
}
}
}
#region UI元素声明
protected Panel Part_Root;
protected Line Part_Line;
protected FrameworkElement Part_Border, Part_ThumbVertical, Part_ThumbHorizontal;
#endregion
protected Point _thumbMouseDown;
protected double _mouseDownValue = - 1 ;
protected bool hasCapture = false ;
protected SliderOrientation _orientation = SliderOrientation.Horizontal;
}
下面代介绍的是ColorSlider控件的控件逻辑cs文件(详情看注释):
///
<summary>
/// 颜色滑动条控制
/// </summary>
public partial class ColorSlider : Slider
{
public ColorSlider()
{
string xaml = ResourceHelper.GetTemplate( this .GetType());
ControlTemplate template = (ControlTemplate)XamlReader.Load(xaml);
this .Template = template;
base .ApplyTemplate();
}
/// <summary>
/// 该方法为本人所加,用户当滑动条方向为“垂直”时,重新设置“GradientBrush”的“EndPoint”属性
/// </summary>
public new SliderOrientation Orientation
{
get { return base .Orientation; }
set
{
base .Orientation = value;
// 当为垂直方向时
if (value == SliderOrientation.Vertical)
{
((LinearGradientBrush)GetTemplateChild( " GradientBrush " )).EndPoint = new Point( 0 , 1 );
}
}
}
/// <summary>
/// 获取颜色值
/// </summary>
/// <returns></returns>
public Color GetColor()
{
return this .GetColor( 255 );
}
/// <summary>
/// 将滑动条值(Value)转换为ARGB 颜色值并返回
/// </summary>
/// <param name="alpha"> alpha通道,该值介于0到255 </param>
/// <returns> ARGB 颜色值 </returns>
public Color GetColor( byte alpha)
{
Color color;
double value = this .Value;
// 将滑动条的值转换为 ARGB 颜色值
if (value < 0.143d )
{
color = Color.FromArgb(alpha, ( byte )Math.Floor((value * 256d) / 0.143d ), 0 , 0 );
}
else if (value < 0.286d )
{
color = Color.FromArgb(alpha, ( byte )Math.Floor(256d * ( 0.286d - value) / 0.143d ),
( byte )Math.Floor(256d * (value - 0.143d ) / 0.143d ), 0 );
}
else if (value < 0.429 )
{
color = Color.FromArgb(alpha, 0 , ( byte )Math.Floor(256d * ( 0.429d - value) / 0.143d ),
( byte )Math.Floor(256d * (value - 0.286d ) / 0.143d ));
}
else if (value < 0.571 )
{
color = Color.FromArgb(alpha, 0 , ( byte )Math.Floor(256d * (value - 0.429d ) / 0.143d ), 255 );
}
else if (value < 0.714 )
{
color = Color.FromArgb(alpha, ( byte )Math.Floor(256d * (value - 0.571d ) / 0.143d ),
( byte )Math.Floor(256d * ( 0.714d - value) / 0.143d ), 255 );
}
else if (value < 0.857 )
{
color = Color.FromArgb(alpha, 255 , ( byte )Math.Floor(256d * (value - 0.714d ) / 0.143d ),
( byte )Math.Floor(256d * ( 0.857d - value) / 0.143d ));
}
else
{
color = Color.FromArgb(alpha, 255 , 255 , ( byte )Math.Floor(256d * (value - 0.857d ) / 0.143d ));
}
return color;
}
}
/// 颜色滑动条控制
/// </summary>
public partial class ColorSlider : Slider
{
public ColorSlider()
{
string xaml = ResourceHelper.GetTemplate( this .GetType());
ControlTemplate template = (ControlTemplate)XamlReader.Load(xaml);
this .Template = template;
base .ApplyTemplate();
}
/// <summary>
/// 该方法为本人所加,用户当滑动条方向为“垂直”时,重新设置“GradientBrush”的“EndPoint”属性
/// </summary>
public new SliderOrientation Orientation
{
get { return base .Orientation; }
set
{
base .Orientation = value;
// 当为垂直方向时
if (value == SliderOrientation.Vertical)
{
((LinearGradientBrush)GetTemplateChild( " GradientBrush " )).EndPoint = new Point( 0 , 1 );
}
}
}
/// <summary>
/// 获取颜色值
/// </summary>
/// <returns></returns>
public Color GetColor()
{
return this .GetColor( 255 );
}
/// <summary>
/// 将滑动条值(Value)转换为ARGB 颜色值并返回
/// </summary>
/// <param name="alpha"> alpha通道,该值介于0到255 </param>
/// <returns> ARGB 颜色值 </returns>
public Color GetColor( byte alpha)
{
Color color;
double value = this .Value;
// 将滑动条的值转换为 ARGB 颜色值
if (value < 0.143d )
{
color = Color.FromArgb(alpha, ( byte )Math.Floor((value * 256d) / 0.143d ), 0 , 0 );
}
else if (value < 0.286d )
{
color = Color.FromArgb(alpha, ( byte )Math.Floor(256d * ( 0.286d - value) / 0.143d ),
( byte )Math.Floor(256d * (value - 0.143d ) / 0.143d ), 0 );
}
else if (value < 0.429 )
{
color = Color.FromArgb(alpha, 0 , ( byte )Math.Floor(256d * ( 0.429d - value) / 0.143d ),
( byte )Math.Floor(256d * (value - 0.286d ) / 0.143d ));
}
else if (value < 0.571 )
{
color = Color.FromArgb(alpha, 0 , ( byte )Math.Floor(256d * (value - 0.429d ) / 0.143d ), 255 );
}
else if (value < 0.714 )
{
color = Color.FromArgb(alpha, ( byte )Math.Floor(256d * (value - 0.571d ) / 0.143d ),
( byte )Math.Floor(256d * ( 0.714d - value) / 0.143d ), 255 );
}
else if (value < 0.857 )
{
color = Color.FromArgb(alpha, 255 , ( byte )Math.Floor(256d * (value - 0.714d ) / 0.143d ),
( byte )Math.Floor(256d * ( 0.857d - value) / 0.143d ));
}
else
{
color = Color.FromArgb(alpha, 255 , 255 , ( byte )Math.Floor(256d * (value - 0.857d ) / 0.143d ));
}
return color;
}
}
接着再来看一下如何使用这两个控件(也就是本文第一张图所演示的效果),其page逻辑代码如下:
public
partial
class
Page2 : UserControl
{
public Page2()
{
InitializeComponent();
#region Slider测试代码,加载图片并添加演示缩放旋转的Transform
string baseUri = Application.Current.Host.Source.AbsoluteUri.Substring( 0 ,
Application.Current.Host.Source.AbsoluteUri.LastIndexOf( " / " ));
currentImage.SetValue(Image.SourceProperty, new BitmapImage(
new Uri(String.Concat(baseUri, " /../Images/j0433157.jpg " ))));
TransformGroup transforms = new TransformGroup();
transforms.Children.Add( new ScaleTransform());
transforms.Children.Add( new RotateTransform());
currentImage.RenderTransform = transforms;
currentImage.RenderTransformOrigin = new Point( 0.5 , 0.5 );
#endregion
}
#region Slider示例代码
void ColorSlider_ValueChanged( object sender, EventArgs e)
{
// 水平Slider设置背景色
SliderPanel.Background = new SolidColorBrush(ColorSlider.GetColor());
}
void ColorSlider2_ValueChanged( object sender, EventArgs e)
{
// 垂直Slider设置背景色
SliderPanel2.Background = new SolidColorBrush(ColorSlider2.GetColor());
}
private void opacitySlider_ValueChanged( object sender, EventArgs e)
{
// 设置图像的Opacity属性
currentImage.Opacity = 1d - opacitySlider.Value;
}
private void transformSlider_ValueChanged( object sender, EventArgs e)
{
// 设置旋转属性
((RotateTransform)((TransformGroup)currentImage.RenderTransform).Children[ 1 ]).Angle =
(transformSlider.Value - 0.5d ) * 720d;
// 设置缩放属性
((ScaleTransform)((TransformGroup)currentImage.RenderTransform).Children[ 0 ]).ScaleX =
transformSlider.Value * 2d;
((ScaleTransform)((TransformGroup)currentImage.RenderTransform).Children[ 0 ]).ScaleY =
transformSlider.Value * 2d;
}
#endregion
}
{
public Page2()
{
InitializeComponent();
#region Slider测试代码,加载图片并添加演示缩放旋转的Transform
string baseUri = Application.Current.Host.Source.AbsoluteUri.Substring( 0 ,
Application.Current.Host.Source.AbsoluteUri.LastIndexOf( " / " ));
currentImage.SetValue(Image.SourceProperty, new BitmapImage(
new Uri(String.Concat(baseUri, " /../Images/j0433157.jpg " ))));
TransformGroup transforms = new TransformGroup();
transforms.Children.Add( new ScaleTransform());
transforms.Children.Add( new RotateTransform());
currentImage.RenderTransform = transforms;
currentImage.RenderTransformOrigin = new Point( 0.5 , 0.5 );
#endregion
}
#region Slider示例代码
void ColorSlider_ValueChanged( object sender, EventArgs e)
{
// 水平Slider设置背景色
SliderPanel.Background = new SolidColorBrush(ColorSlider.GetColor());
}
void ColorSlider2_ValueChanged( object sender, EventArgs e)
{
// 垂直Slider设置背景色
SliderPanel2.Background = new SolidColorBrush(ColorSlider2.GetColor());
}
private void opacitySlider_ValueChanged( object sender, EventArgs e)
{
// 设置图像的Opacity属性
currentImage.Opacity = 1d - opacitySlider.Value;
}
private void transformSlider_ValueChanged( object sender, EventArgs e)
{
// 设置旋转属性
((RotateTransform)((TransformGroup)currentImage.RenderTransform).Children[ 1 ]).Angle =
(transformSlider.Value - 0.5d ) * 720d;
// 设置缩放属性
((ScaleTransform)((TransformGroup)currentImage.RenderTransform).Children[ 0 ]).ScaleX =
transformSlider.Value * 2d;
((ScaleTransform)((TransformGroup)currentImage.RenderTransform).Children[ 0 ]).ScaleY =
transformSlider.Value * 2d;
}
#endregion
}
好了,今天的内容就先到这里了。
tag:silverlight,slider,colorslider,imagesnipper
作者:代震军,daizhj
原文链接:http://www.cnblogs.com/daizhj/archive/2008/09/04/1284228.html
源码下载,请 点击这里:)