Shapes, gradients và brushes cung cấp cho người dùng nhiều quyền hạn
để tạo ra nhiều control theo ý của họ và nhìn đẹp mắt hơn. Thí dụ, gradients có
thể tạo ra những hình ảnh nhìn giống như bị che khuất chỉ 1 phần (shadows) hay sáng
lên 1 phần (lighting) rất đẹp. Và còn demo này, chúng ta sẽ tạo ra điều cuối
cùng là 1 cái đồng hồ, hay là các kiểu đồng hồ khác. Hình sau đây sẽ là tất cả
những điều chúng ta làm trong bài học này.

Trước khi chúng ta làm cái đồng hồ
này, hãy nhìn các thuộc tính mà sẽ tạo nên các control này:
Các phần tử của Shapes :
Silverlight hỗ trợ những cái gì được gọi là đồ họa vector và
cung cấp các hình cơ bản sau:
- Ellipse
- Mô tả 1 hình bầu dục (oval) hay 1 hình tròn.
- Rectangle
- Mô tả hình chữ nhật hay hình vuông (có thể làm tròn các góc).
- Line
- Mô tả 1 đường thẳng được nối bởi 2 điểm.
- Polygon
- Mô tả hình đóng (đa giác) với số cạnh tùy ý.
- Polyline
- Mô tả một loạt các đường thẳng kết nối mà có thể tạo thành hay không thành một
hình đóng.
- Path - Mô tả những hình phức tạp bao gồm các hình cung,
cong, lõm.
Màu sắc:
Màu sắc có thể được sử dụng theo các
dạng sau:
- Tên của màu ví dụ như "Red", "Blue", "Black", vv....
- Một chữ 6 chữ số RGB(red, green, blue) kí hiệu là #rrggbb với mỗi rr, gg và bb là hai giá trị thập phân mô tả số
lượng màu của các màu đỏ, xanh lá và xanh đậm ( red, green and blue) tương
ứng. Thí dụ: #FF0000 sẽ là màu đỏ tươi sáng.
- Một kí hiệu 8 chữ số ARGB (alpha, red, green, blue) kí hiệu
với hai giá trị mở rộng ở đầu là giá trị alpha mô tả độ trong suốt của màu (opacity). Thí dụ, #FFFF0000 sẽ là màu đỏ tươi sáng và trong suốt.
Fill & Stroke:
Shapes có hai phần , đường bao bên
ngoài (border) và phần bên trong. Màu sắc của những phần này được điều khiển
bởi hai thuộc tính Stroke và Fill. Một số shape như là một Line chỉ có 1 stroke (chỉ cần tô màu
bằng thuộc tính stroke là được). Đặc
biệt nếu là một Fill dành cho đường thẳng ( line) không có hiệu ứng.
(Tức là theo mình hiểu thì stroke là tô màu đường viền, còn Fill là tô màu bên trong đường viền. Đường thẳng thì chỉ có 1 đường nên chỉ có thuộc tính Stroke.)

Brushes
Sử dụng <Ellipse.Fill> chúng ta có thể tô màu
cho ellipse này sử dụng một trong các lựa chọn brush sau:
- A linear gradient brush - Tô màu dọc theo một đường thẳng với độ đậm nhạt khác
nhau. Đường thẳng là dường chéo và
giãn ra từ phía trên bên trái cho đến phía thấp bên phải theo mặc định. Những
thuộc tính StartPoint và EndPoint có thể thay đổi các vị
trí này.
- A Image brush
- Tô màu bằng 1 hình ảnh.
- A radial gradient brush - Tô màu dọc theo một hình tròn. Mặc dịnh, hình tròn
nẳm ở trung tâm khu vực đang tô màu.
- A solid color brush
- Tô màu cho một khu vực với một màu solid (thuần nhất).
- A video brush
- Tô màu 1 khu vực với 1 đoạn video.
Đây là thí dụ:

Và giống như thứ tự xuất hiện trong
code sau:
<MediaElement Canvas.Top="300" x:Name="MyMedia" Source="MyVideo.wmv" Width="300" Height="300" />
<Ellipse Canvas.Top="20" Canvas.Left="5" Width="100" Height="100" StrokeThickness="2">
<Ellipse.Fill>
<LinearGradientBrush
StartPoint='0.1,0.06'
EndPoint='0.5,0.6'>
<GradientStop Color='#FFFFFFFF' Offset='0'/>
<GradientStop Color='#FF000000' Offset='1'/>
</LinearGradientBrush>
</Ellipse.Fill>
</Ellipse>
<Ellipse Canvas.Top="20" Canvas.Left="105" Width="100" Height="100" StrokeThickness="2">
<Ellipse.Fill>
<ImageBrush ImageSource="clock.png" Stretch="Uniform"></ImageBrush>
</Ellipse.Fill>
</Ellipse>
<Ellipse Canvas.Top="20" Canvas.Left="205" Width="100" Height="100" StrokeThickness="2">
<Ellipse.Fill>
<RadialGradientBrush>
<GradientStop Color="Yellow" Offset="0.0" />
<GradientStop Color="Red" Offset="1.0" />
</RadialGradientBrush>
</Ellipse.Fill>
</Ellipse>
<Ellipse Canvas.Top="20" Canvas.Left="305" Width="100" Height="100" StrokeThickness="2">
<Ellipse.Fill>
<SolidColorBrush Color="Blue"/>
</Ellipse.Fill>
</Ellipse>
<Ellipse Canvas.Top="20" Canvas.Left="405" Width="100" Height="100" StrokeThickness="2">
<Ellipse.Fill>
<VideoBrush SourceName="MyMedia" />
</Ellipse.Fill>
</Ellipse>
Còn về phần Video brush, hãy chắc là đoạn video ấy được đặt trong thư
mục ClientBin của bạn.
Bắt tay vào việc tạo đồng hồ! Chúng ta bắt đầu bằng 1 hình ellipse đơn giản
nằm trong một đối tượng <Canvas> với chiều rộng và chiều cao Width và Height là 200. Với thuộc tính Fill, chúng ta sẽ dùng LinearGradientBrush:
<Grid x:Name="LayoutRoot" Background="Gray">
<Canvas x:Name="Clock">
<Ellipse Canvas.Top="150" Canvas.Left="5" Width="200" Height="200" StrokeThickness="2">
<Ellipse.Fill>
<LinearGradientBrush StartPoint='0.1,0.06' EndPoint='0.5,0.6'>
<GradientStop Color='#FFFFFFFF' Offset='0'/>
<GradientStop Color='#FF000000' Offset='1'/>
</LinearGradientBrush>
</Ellipse.Fill>
</Ellipse>
</Canvas>
</Grid>
Những dòng code này tạo ra hình tròn như sau:

Hãy thêm vào một hình tròn nhỏ khác ở trung tâm , cộng thêm 2 hay 3 đường màu
đỏ để tạo kim giờ và kim phút cho đồng hồ.
<Line X1="100" X2="25" Y1="246" Y2="247" Stroke="Red" StrokeThickness="1" />
<Line X1="100" X2="25" Y1="247" Y2="247" Stroke="Red" StrokeThickness="1" />
<Line X1="100" X2="25" Y1="248" Y2="247" Stroke="Red" StrokeThickness="1" />
<Line X1="106" X2="60" Y1="246" Y2="290" Stroke="Red" StrokeThickness="1" />
<Line X1="106" X2="60" Y1="247" Y2="290" Stroke="Red" StrokeThickness="1" />
<Line X1="106" X2="60" Y1="248" Y2="290" Stroke="Red" StrokeThickness="1" />
<Ellipse Width="15" Height="15" Canvas.Left="100" Canvas.Top="240">
<Ellipse.Fill>
<LinearGradientBrush
StartPoint='0.1,0.06'
EndPoint='0.5,0.6'>
<GradientStop Color='#FFFFFFFF' Offset='0'/>
<GradientStop Color='#FF000000' Offset='1'/>
</LinearGradientBrush>
</Ellipse.Fill>
</Ellipse>

Và cuối cùng , còn về những con số chúng ta sẽ tạo
ra chúng và thêm chúng vào như là Textblocks. Chúng ta làm điều
này bằng việc tính toán vị
trí X & Y dọc theo một vòng tròn với một bán
kính là 85 pixels. Mỗi con số cách nhau 30 độ. Chúng ta bắt đầu là 1:00 nằm ở vị trí 1 góc 300 độ.
1: private void AddNumbers()
2: {
3: double angle = 300;
4: for (int i = 1; i < 13; i++)
5: {
6: TextBlock tb = new TextBlock();
7: tb.Foreground = new SolidColorBrush(Colors.White);
8: tb.Text = i.ToString();
9:
10: double radians = angle * (Math.PI / 180);
11: double radius = 85;
12: int x = (int)(radius * Math.Cos(radians));
13: int y = (int)(radius * Math.Sin(radians));
14: tb.SetValue(Canvas.LeftProperty, (double) x+97);
15: tb.SetValue(Canvas.TopProperty, (double) y+239);
16:
17: angle += 30;
18: Clock.Children.Add(tb);
19: }
20: }
Đây là kết quả cuối cùng:

Thank you,
--Mike Snow