天天看點

一起談.NET技術,Silverlight中自定義控件

  自定義控件并不是一項多麼難的技術,關于自定義控件這部分有不少文章講的很透徹,這裡我主要把自己練習自定義控件的過程記錄下來。

  這裡我以自定義控件BusyPointer為例,首先我們建立一個應用程式,命名為CustomControl,這裡我們将自定義控件放入單獨的項目中,是以在解決方案裡添加一個Silverlight Class Library項目,命名為BusyPointer,現在我們把Class1.cs類删除,然後在BusyPointer項目中添加一個Silverlight Template Control,我們為之命名為BusyPoint,這時架構如下圖所示,項目中增加了一個類檔案,同時增加了名為Generic的xaml檔案。            

一起談.NET技術,Silverlight中自定義控件

  現在我們開始定義控件邏輯對于BusyPoint這個控件,這裡我們隻是簡單模仿Win7裡一個滑鼠行為在BusyPoint.cs檔案中給其定義了一個依賴屬性。

public bool IsBusy

{

get

return (bool)GetValue(IsBusyProperty);

}

set

SetValue(IsBusyProperty, value);

ChangeState();

private void ChangeState()

if (IsBusy) VisualStateManager.GoToState(this, "Busied", true);

else VisualStateManager.GoToState(this, "Normal", true);

public static readonly DependencyProperty IsBusyProperty =

DependencyProperty.Register("IsBusy", typeof(bool), typeof(BusyPoint), new PropertyMetadata(new PropertyChangedCallback(OnBusyChanged)));

private static void OnBusyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)

((BusyPoint)sender).IsBusy = (bool)e.NewValue;

  關于依賴屬性這個部分就不細說了,這裡我們聲明了一個用于當IsBusy值發生變化時的回調方法OnBusyChanged,現在我們在Generic.xaml中定義控件的樣式。

<Style TargetType="local:BusyPoint">

<Setter Property="Template">

<Setter.Value>

<ControlTemplate TargetType="local:BusyPoint">

<Grid x:Name="LayoutRoot" Background="Transparent">

<vsm:VisualStateManager.VisualStateGroups>

<vsm:VisualStateGroup x:Name="CommonStates">

<vsm:VisualState x:Name="Normal" />

<vsm:VisualState x:Name="Busied">

<Storyboard>

<DoubleAnimationUsingKeyFrames Storyboard.TargetName="VisualElement" Storyboard.TargetProperty="(UIElement.RenderTransform).Angle" RepeatBehavior="Forever">

<SplineDoubleKeyFrame KeyTime="0:0:1" Value="360" />

</DoubleAnimationUsingKeyFrames>

</Storyboard>

</vsm:VisualState>

</vsm:VisualStateGroup>

</vsm:VisualStateManager.VisualStateGroups>

<Ellipse Width="20" Height="20" StrokeThickness="5.5" x:Name="VisualElement">

<Ellipse.Stroke>

<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">

<GradientStop Color="#FF096475" Offset="0.571" />

<GradientStop Color="#FFA8FCFC" Offset="1" />

</LinearGradientBrush>

</Ellipse.Stroke>

<Ellipse.RenderTransform>

<RotateTransform CenterX="12.5" CenterY="12.5" />

</Ellipse.RenderTransform>

</Ellipse>

</Grid>

</ControlTemplate>

</Setter.Value>

 </Style>

  這裡我們還需要添加一下命名空間xmlns:vsm="clr:namespace:System.Windows;assembly=System.Windows"

一起談.NET技術,Silverlight中自定義控件

  dll添加完成後,我們在MainPage.xaml頁面中添加一個引用xmlns:by="clr-namespace:BusyPointer;assembly=BusyPointer",UI代碼如下:

<by:BusyPoint x:Name="busy" IsBusy="False"></by:BusyPoint>

<Button Content="Button" Name="button1" Click="button1_Click" />

  這裡我們将BusyPoint控件的IsBusy設為False,我們通過這個Button将其設為True。

this.busy.IsBusy = true;

一起談.NET技術,Silverlight中自定義控件

  雖然比起系統自帶的滑鼠頭不怎麼優雅,當然這個部分并不是重點了,隻是以這個控件為例,将自定義控件的步驟梳理了一遍。