SnipperImages(Silverlight DEMO)控件设计之--Slider和ColorSlider
生活随笔
收集整理的這篇文章主要介紹了
SnipperImages(Silverlight DEMO)控件设计之--Slider和ColorSlider
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
在上一篇文章中,介紹了CheckBox控件的開發方式,包括xaml和控件邏輯(cs代碼控制xaml中UI元素)。本文所要介紹的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>
??? 從上面代碼可以看出,Slider由四個主要元素組成:
Part_Border:用于繪制背景色(如ColorSlider控件的背景色)
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>
????? 說完了xaml,下面開始介紹cs控件邏輯代碼。
????? 首先要說的是一個枚舉類型,用于標識滑動方向(垂直或水平):
///?<summary>
///?滑動條方向類型
///?</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;
}
?????? 下面代介紹的是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;
????}
}
????? 接著再來看一下如何使用這兩個控件(也就是本文第一張圖所演示的效果),其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
}
???? 好了,今天的內容就先到這里了。
???? tag:silverlight,slider,colorslider,p_w_picpathsnipper
???? 作者:代震軍,daizhj
???? 原文鏈接:[url]http://www.cnblogs.com/daizhj/archive/2008/09/04/1284228.html[/url]
???? ×××,請點擊這里:)
???? 好了,開始今天的正文。
???? 首先看一下這個演示頁,如下:
注:因為我從網上所獲得的源碼中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>
??? 從上面代碼可以看出,Slider由四個主要元素組成:
Part_Border:用于繪制背景色(如ColorSlider控件的背景色)
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>
????? 說完了xaml,下面開始介紹cs控件邏輯代碼。
????? 首先要說的是一個枚舉類型,用于標識滑動方向(垂直或水平):
///?<summary>
///?滑動條方向類型
///?</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;
}
?????? 下面代介紹的是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;
????}
}
????? 接著再來看一下如何使用這兩個控件(也就是本文第一張圖所演示的效果),其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
}
???? 好了,今天的內容就先到這里了。
???? tag:silverlight,slider,colorslider,p_w_picpathsnipper
???? 作者:代震軍,daizhj
???? 原文鏈接:[url]http://www.cnblogs.com/daizhj/archive/2008/09/04/1284228.html[/url]
???? ×××,請點擊這里:)
轉載于:https://blog.51cto.com/daizhj/100973
總結
以上是生活随笔為你收集整理的SnipperImages(Silverlight DEMO)控件设计之--Slider和ColorSlider的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 转换字符串为json对象的方法
- 下一篇: Python天天美味(32) - pyt