UML软件工程组织

Fun with Silverlight系列

 

2008-03-27 作者: 柳暗花明 出处: cnblogs.com

 


Fun with Silverlight系列之一 -- 倒影效果

在Silverlight中实现倒影效果和在WPF中稍有不同,

在WPF中可以用VisualBrush 实现,具体如下:

要反射的内容:

 1<Border Name="inkBorder" Grid.Row="0" VerticalAlignment="Bottom" Margin="20"
 2            Width="400" Height="100" CornerRadius="5" BorderThickness="4">
 3      <Border.BorderBrush>
 4        <LinearGradientBrush SpreadMethod="Reflect" StartPoint="0,0" EndPoint="0.5,0.5">
 5       <LinearGradientBrush.GradientStops>
 6         <GradientStop Color="Gray" Offset="0" />
 7            <GradientStop Color="#eeeeee" Offset="1" />
 8          </LinearGradientBrush.GradientStops>
 9         </LinearGradientBrush>
10      </Border.BorderBrush>
11      <InkCanvas Background="Yellow">
12         <Line X1="10" Y1="70" X2="380" Y2="70" Stroke="Gray"/>
13      </InkCanvas>
14    </Border>

倒影内容:

 1  <Rectangle.Fill>
 2    <VisualBrush
 3      Visual="{Binding ElementName=inkBorder}">
 4      <VisualBrush.RelativeTransform>
 5        <TransformGroup>
 6          <ScaleTransform ScaleX="1" ScaleY="-1" />
 7          <TranslateTransform Y="1" />
 8        </TransformGroup>
 9      </VisualBrush.RelativeTransform>
10    </VisualBrush>
11  </Rectangle.Fill>

关键在于这句话<ScaleTransform ScaleX="1" ScaleY="-1" /> 表示控件的反转效果,后面也会用到这个技巧。

在Silverlight中有ImageBrush和VideoBrush,可以类似WPF里的方法倒映图片和视频

例如:

 1<Canvas 
 2  xmlns="http://schemas.microsoft.com/client/2007"
 3  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 4  Width="346" Height="516">
 5  <MediaElement Width="328" Height="248" Canvas.Left="8" Canvas.Top="8"
 6                x:Name="video" Source="Bear.wmv" Stretch="Fill" /> 
 7
 8  <Rectangle Width="328" Height="248" Canvas.Left="8" Canvas.Top="506">
 9    <Rectangle.Fill>
10      <VideoBrush SourceName="video" />
11    </Rectangle.Fill>
12    <Rectangle.RenderTransform>
13      <ScaleTransform ScaleX="1" ScaleY="-1"/>
14    </Rectangle.RenderTransform>
15    <Rectangle.OpacityMask>
16      <LinearGradientBrush EndPoint="0.5,0.605" StartPoint="0.5,0.94">
17        <GradientStop Color="#64000000" Offset="0"/>
18        <GradientStop Color="#00FFFFFF" Offset="1"/>
19      </LinearGradientBrush>
20    </Rectangle.OpacityMask>
21  </Rectangle>
22</Canvas>
23
24

但是如果向反射其他控件的话就要自己写代码控制了,我们要反映这个控件:

1  <InkPresenter Name="inkPresenter" Canvas.Left="70" Canvas.Top="50" 
Background
="Transparent" Cursor="Stylus" MouseLeftButtonDown="onMouseDown" 
MouseMove
="onMouseMove" MouseLeftButtonUp="onMouseUp">
2    <InkPresenter.Clip>
3      <RectangleGeometry Rect="0,0,400,100"/>
4    </InkPresenter.Clip>
5    <Image Source="inkbackground.jpg"/>
6    <TextBlock Name="writeHere" Text="Write Here" FontSize="72" 
FontFamily
="Comic Sans MS" Foreground="#80808080" Opacity="1"/>
7  </InkPresenter>

我们可以看到这个控件:

首先在下面添加相同的控件:

1  <InkPresenter Canvas.Left="70" Canvas.Top="180" Name="inkMirror" Width="400"
 Height
="100" RenderTransformOrigin="0.5,0.5">
2    <Rectangle Width="400" Height="100">
3      <Rectangle.Fill>
4        <ImageBrush ImageSource="inkbackground.jpg"/>
5      </Rectangle.Fill>
6    </Rectangle>
7    <TextBlock Name="writeHereMirror" Text="Write Here" FontSize="72"
 FontFamily
="Comic Sans MS" Foreground="#80808080">
8    </TextBlock>
9  </InkPresenter>

效果:

现在设置添加ScaleTransform 并且添加Y轴属性为-1,反转这个控件

 1  <InkPresenter Canvas.Left="70" Canvas.Top="180" Name="inkMirror" Width="400" Height="100" 
 2
 3RenderTransformOrigin="0.5,0.5">

 4    <InkPresenter.RenderTransform>
 5      <TransformGroup>
 6        <ScaleTransform ScaleX="1" ScaleY="-1" />
 7        <TranslateTransform Y="1" />
 8      </TransformGroup>
 9    </InkPresenter.RenderTransform>
10    <Rectangle Width="400" Height="100">
11      <Rectangle.Fill>
12        <ImageBrush ImageSource="inkbackground.jpg"/>
13      </Rectangle.Fill>
14    </Rectangle>
15    <TextBlock Name="writeHereMirror" Text="Write Here" 
FontSize
="72" FontFamily="Comic Sans MS" 
16
17Foreground="#80808080">

18    </TextBlock>
19  </InkPresenter>

现在看一下反转的效果:

不过这种直截了当的倒影似乎并不符合我们的审美观,让我们再添加一些渐变效果让控件仿佛倒影在水中一般

 1  <InkPresenter Canvas.Left="70" Canvas.Top="180" Name="inkMirror" Width="400" Height="100" 
 2
 3RenderTransformOrigin="0.5,0.5">
 4    <InkPresenter.RenderTransform>
 5      <TransformGroup>
 6        <ScaleTransform ScaleX="1" ScaleY="-1" />
 7        <TranslateTransform Y="1" />
 8      </TransformGroup>
 9    </InkPresenter.RenderTransform>
10    <Rectangle Width="400" Height="100">
11      <Rectangle.OpacityMask>
12        <LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1">
13          <LinearGradientBrush.GradientStops>
14            <GradientStop Offset="1.0" Color="#66000000" />
15            <GradientStop Offset="0.0" Color="#00000000" />
16          </LinearGradientBrush.GradientStops>
17        </LinearGradientBrush>
18      </Rectangle.OpacityMask>
19      <Rectangle.Fill>
20        <ImageBrush ImageSource="inkbackground.jpg"/>
21      </Rectangle.Fill>
22    </Rectangle>
23    <TextBlock Name="writeHereMirror" Text="Write Here" FontSize="72" FontFamily="Comic Sans MS" 
24
25Foreground="#80808080">
26      <TextBlock.OpacityMask>
27        <LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1">
28          <LinearGradientBrush.GradientStops>
29            <GradientStop Offset="1.0" Color="#FF000000" />
30            <GradientStop Offset="0.0" Color="#00000000" />
31          </LinearGradientBrush.GradientStops>
32        </LinearGradientBrush>
33      </TextBlock.OpacityMask>
34    </TextBlock>
35  </InkPresenter>

最终效果如下:

最后控制两个图案同步的是在javascript里面,这里就不详说了,参考附件里的代码,其实在silverlight里还可以做出更多令人惊叹的效果,应该不会逊于Flash和Flex里面的效果的,希望大家能够一起挖掘silverlight里面的无限潜能哦

/Files/ithurricane/InkReflectionsSource.zip

Fun with Silverlight系列之二 -- Accordion多层折叠效果

这一次说一下多层折叠效果在silverlight2中的实现,在Adobe的Flex中自带了Accordion的控件,在silverlight2中目前好像
还没有提供,只好暂且自己实现类似的效果了,我目前暂时实现了效果,代码还有很多不完善的地方,以后打算做成一个控件
封装起来,这回先说一下如何实现Accordion效果吧。

实现平台:VS2008 + Silverlight2

效果图:

鼠标移动到注册上:

鼠标移动到登陆上:

鼠标移动到忘记密码上面:

实现步骤:

首先说一下Xaml的实现代码,要实现各个层的隐藏和现实就要先定义动画效果:

动画定义
主要是四个动作,第一设置具体内容的显示和隐藏,第二设置黄色小箭头的方向,第三是设置矩形框的大小,最后设置标题的黄色背景的显示和隐藏。

再说事件的响应部分,我响应的是鼠标移动的事件MouseEnter
 
1<Rectangle x:Name='imageMenuRect' Width='200' Height='50' RadiusX='15'
 RadiusY
='15' Stroke="White" StrokeThickness='2' Fill="Transparent" 
MouseEnter
="imageMenuRect_MouseEnter"/>

后台代码:
 
 1        private void imageMenuRect_MouseEnter(object sender, MouseEventArgs e)
 2        {
 3            imageMenu.Opacity = 1d;
 4            textMenu.Opacity = 0.4d;
 5            inkMenu.Opacity = 0.4d;
 6            miscMenu.Opacity = 0.4d;
 7            if (imageMenuRect.Height == 50)
 8            {
 9                expandImageMenu.Begin();
10            }

11            else
12            {
13                collapseMenus.Begin();
14            }

15        }

把鼠标移动到的层高亮显示,然后激活动画。

最后我想说一下,因为silverlight起步比Flex晚,的确有很多控件和效果没有Flex的丰富,
希望Silverlight社区多涌现出像flexlib这样的开源控件库,
让Silverlight的世界更加丰富多彩起来。

代码下载