Silverlight之ListBox/Style学习笔记--ListBox版的图片轮换广告

ListBox是一个很有用的控件,其功能直逼Asp.Net中的Repeater,它能实现自定义数据项模板,纵向/横向排列Item(如果扩展一下实现自行折行,几乎就是SL版的Repeater了--实际上WrapPanel已经实现了,不过没有默认集成在SL3中). 

这里推荐一个老外的文章 http://blogs.msdn.com/delay/archive/2008/03/05/lb-sv-faq-examples-notes-tips-and-more-for-silverlight-2-beta-1-s-listbox-and-scrollviewer-controls.aspx 基本上ListBox的各种用法和注意点都在里面了(E文的,只看代码就行了) 

另外关于Style,这个东西刚开始学习时,还以为自己能靠死记硬背掌握绝大多数控件的模板,后来发现这是徒劳!每个控件的默认样式/模板,都有N长,全凭记忆不太现实,我的经验是如果需要定义某一个控件的样式,直接用Blend先编辑副本,得到完整的"样本",然后在此基础上做些修改或删减,这样更可行。

Xaml中的资源是个很庞大的概念:样式,模板,动画,触发器,甚至数据集(引用)...都可以称之为Resource.这一点与web开发中的css完全不同。

在学习Style的过程中,经常会遇到另外一个概念:模板(Template),初期经常被他们搞混淆,其实这二者有明显的区别:Style影响外观,而Template影响内容,它们之间通过绑定联系起来(它们之间的联系也可以这样理解:如果不进行数据绑定,即使定义了模板,最终也不会有内容,既然连内容都没有了,所以也谈不上外观--即所谓的数据驱动UI) 

这里举一个ListBox的例子:

Xaml
< UserControl
    
xmlns ="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x
="http://schemas.microsoft.com/winfx/2006/xaml"     
    x:Class
="ListBoxSilde.UserControl1" >
    
< UserControl.Resources >
        
<!-- 整体样式 -->
        
< Style  x:Key ="ListStyle"  TargetType ="ListBox" >
            
< Setter  Property ="Padding"  Value ="1" />
            
< Setter  Property ="Margin"  Value ="0" />
            
< Setter  Property ="BorderThickness"  Value ="0" />
            
< Setter  Property ="Background"  Value =" {x:Null} " />
        
</ Style >

        
<!-- 排列布局(横向) -->
        
< ItemsPanelTemplate  x:Key ="HorizontalItemPanel" >
            
< StackPanel  Orientation ="Horizontal" />
        
</ ItemsPanelTemplate >

        
<!-- 数据项模板(内容) -->
        
< DataTemplate  x:Key ="DataTemplate" >
            
< TextBlock  Text =" {Binding Index} "  Padding ="0"  Margin ="2" ></ TextBlock >
        
</ DataTemplate >

        
<!-- 数据项样式(外观) -->
        
< Style  x:Key ="ItemStyle"  TargetType ="ListBoxItem" >
            
< Setter  Property ="Template" >
                
< Setter.Value >
                    
< ControlTemplate >
                        
< Grid  Cursor ="Hand" >
                            
< VisualStateManager.VisualStateGroups >
                                
< VisualStateGroup  x:Name ="SelectionStates" >
                                    
< VisualState  x:Name ="Unselected" />
                                    
< VisualState  x:Name ="Selected" >
                                        
< Storyboard >
                                            
< DoubleAnimationUsingKeyFrames  Storyboard.TargetName ="fillColor2"  Storyboard.TargetProperty ="Opacity" >
                                                
< SplineDoubleKeyFrame  KeyTime ="0"  Value ="0.75" />
                                            
</ DoubleAnimationUsingKeyFrames >
                                        
</ Storyboard >
                                    
</ VisualState >
                                
</ VisualStateGroup >
                            
</ VisualStateManager.VisualStateGroups >
                            
< Rectangle  Fill ="#99FFFFFF"  IsHitTestVisible ="False"  Margin ="1" />
                            
< Rectangle  x:Name ="fillColor2"  Fill ="#FFBADDE9"  RadiusX ="0"  RadiusY ="0"  IsHitTestVisible ="False"  Opacity ="0"  Margin ="1" />
                            
< ContentPresenter  x:Name ="contentPresenter"  Content =" {TemplateBinding Content} "  Margin ="2" />
                        
</ Grid >
                    
</ ControlTemplate >
                
</ Setter.Value >
            
</ Setter >
        
</ Style >

    
</ UserControl.Resources >

    
< StackPanel  Background ="DarkBlue" >
        
< ListBox  x:Name ="lst"  HorizontalAlignment ="Center"  VerticalAlignment ="Center"  Style =" {StaticResource ListStyle} "  ItemsPanel =" {StaticResource HorizontalItemPanel} "  ItemTemplate =" {StaticResource DataTemplate} "  ItemContainerStyle =" {StaticResource ItemStyle} " >
        
</ ListBox >
    
</ StackPanel >
</ UserControl >

 这段代码中,ListBox本身空空如也(除了几个样式和模板的应用),最终的呈现内容和外观,全部在UserControl.Resource中定义了,运行后界面肯定是空的,因为没有数据绑定,我们给它加上后端代码:

Xaml.cs
using  System.Windows.Controls;
using  System.Reflection;
using  System.Collections.Generic;

namespace  ListBoxSilde
{
    
public   partial   class  UserControl1 : UserControl
    {
        Test t;

        
public  UserControl1()
        {            
            InitializeComponent();

            List
< Test >  lst  =   new  List < Test > (){
                
new  Test(){ Index = " 1 " },
                
new  Test(){ Index = " 2 " },
                
new  Test(){ Index = " 3 " },
                
new  Test(){ Index = " 4 " },
                
new  Test(){ Index = " 5 " }
            };

            
this .lst.ItemsSource  =  lst;
        }
    }

    
public   class  Test {  public   string  Index {  set get ; } }     
}

运行后的样子类似这样:


下面这个效果是很多网站都有的图片广告轮换,当然实现办法有N多,这里我用Style结合ListBox弄了一个: 

大致思路:用style定义ListBox的ItemsPanel,把默认纵向排列改成横向排列,然后结合Clip属性设置可视区(蒙板),让其左右移动即可。

xaml代码:

代码
< UserControl
    
xmlns ="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  
    xmlns:x
="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d
="http://schemas.microsoft.com/expression/blend/2008"  xmlns:mc ="http://schemas.openxmlformats.org/markup-compatibility/2006"  
    mc:Ignorable
="d"   x:Class ="ListBoxSilde.MainPage"
    d:DesignWidth
="640"  d:DesignHeight ="480" >

    
< UserControl.Resources >

        
<!-- 整体样式 -->
        
< Style  x:Key ="ListStyle"  TargetType ="ListBox" >
            
< Setter  Property ="Padding"  Value ="1" />
            
< Setter  Property ="Margin"  Value ="0" />
            
< Setter  Property ="BorderThickness"  Value ="0" />
            
< Setter  Property ="Background"  Value =" {x:Null} " />
        
</ Style >

        
<!-- 排列布局(横向) -->
        
< ItemsPanelTemplate  x:Key ="HorizontalItemPanel" >
            
< StackPanel  Orientation ="Horizontal" />
        
</ ItemsPanelTemplate >

        
<!-- 导航区-数据项模板(内容) -->
        
< DataTemplate  x:Key ="NavDataTemplate" >
            
< StackPanel  MouseLeftButtonDown ="NavItemClick"  Background ="#00000000" >
                
< TextBlock  Text =" {Binding Index} "  Padding ="0"  Margin ="2,0" ></ TextBlock >
            
</ StackPanel >
        
</ DataTemplate >

        
<!-- 导航区-数据项样式(外观) -->
        
< Style  x:Key ="NavItemStyle"  TargetType ="ListBoxItem" >
            
< Setter  Property ="Template" >
                
< Setter.Value >
                    
< ControlTemplate >
                        
< Grid  Cursor ="Hand" >
                            
< VisualStateManager.VisualStateGroups >
                                
< VisualStateGroup  x:Name ="SelectionStates" >
                                    
< VisualState  x:Name ="Unselected" />
                                    
< VisualState  x:Name ="Selected" >
                                        
< Storyboard >
                                            
< DoubleAnimationUsingKeyFrames  Storyboard.TargetName ="fillColor2"  Storyboard.TargetProperty ="Opacity" >
                                                
< SplineDoubleKeyFrame  KeyTime ="0"  Value ="0.85" />
                                            
</ DoubleAnimationUsingKeyFrames >
                                        
</ Storyboard >
                                    
</ VisualState >
                                
</ VisualStateGroup >
                            
</ VisualStateManager.VisualStateGroups >
                            
< Rectangle  Fill ="#99FFFFFF"  IsHitTestVisible ="False"  Margin ="1" />
                            
< Rectangle  x:Name ="fillColor2"  Fill ="#FFBADDE9"  RadiusX ="0"  RadiusY ="0"  IsHitTestVisible ="False"  Opacity ="0"  Margin ="1" />
                            
< ContentPresenter  x:Name ="contentPresenter"  Content =" {TemplateBinding Content} "  Margin ="2" />
                        
</ Grid >
                    
</ ControlTemplate >
                
</ Setter.Value >
            
</ Setter >
        
</ Style >

        
<!-- 图片区-数据项模板 -->
        
< DataTemplate  x:Key ="ImageDataTemplate" >
            
< Image  Margin ="0"  Source =" {Binding ImageUri} "  Stretch ="UniformToFill"  Height ="300.0"  Width ="480.0"  ToolTipService.ToolTip =" {Binding Title} "  Cursor ="Hand"  MouseLeftButtonDown ="Image_MouseLeftButtonDown"  x:Name =" {Binding Index} "   />
        
</ DataTemplate >

        
<!-- 图片区-数据项外观 -->
        
< Style  x:Key ="ImageItemStyle"  TargetType ="ListBoxItem" >
            
< Setter  Property ="Template" >
                
< Setter.Value >
                    
< ControlTemplate >
                        
< ContentPresenter  x:Name ="contentPresenter"  Content =" {TemplateBinding Content} "  Margin ="0" />
                    
</ ControlTemplate >
                
</ Setter.Value >
            
</ Setter >
        
</ Style >

        
<!-- 动画 -->
        
< Storyboard  x:Name ="sbMove" >
            
< DoubleAnimationUsingKeyFrames  BeginTime ="00:00:00"  Storyboard.TargetName ="lstImage"  Storyboard.TargetProperty ="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)" >
                
< EasingDoubleKeyFrame  KeyTime ="00:00:00.5000000"  Value ="-481"  x:Name ="kTo" >
                    
< EasingDoubleKeyFrame.EasingFunction >
                        
< BackEase  EasingMode ="EaseInOut"  Amplitude ="0.5" />
                    
</ EasingDoubleKeyFrame.EasingFunction >
                
</ EasingDoubleKeyFrame >
            
</ DoubleAnimationUsingKeyFrames >
        
</ Storyboard >

    
</ UserControl.Resources >

    
< Grid  x:Name ="LayoutRoot"  ShowGridLines ="True"  Height ="300"  Width ="480"  MouseEnter ="LayoutRoot_MouseEnter"  MouseLeave ="LayoutRoot_MouseLeave" >
        
< Grid.Clip >
            
< RectangleGeometry  Rect ="0,0,480,300" />
        
</ Grid.Clip >

        
< Canvas >
            
< ListBox  x:Name ="lstImage"  Style =" {StaticResource ListStyle} "  ItemsPanel =" {StaticResource HorizontalItemPanel} "  ItemContainerStyle =" {StaticResource ImageItemStyle} "  ItemTemplate =" {StaticResource ImageDataTemplate} "  RenderTransformOrigin ="0.5,0.5"  Padding ="0" >
                
< ListBox.RenderTransform >
                    
< TransformGroup >
                        
< ScaleTransform />
                        
< SkewTransform />
                        
< RotateTransform />
                        
< TranslateTransform />
                    
</ TransformGroup >
                
</ ListBox.RenderTransform >
            
</ ListBox >
        
</ Canvas >

        
< ListBox  Style =" {StaticResource ListStyle} "  ItemsPanel =" {StaticResource HorizontalItemPanel} "  ItemContainerStyle =" {StaticResource NavItemStyle} "  ItemTemplate =" {StaticResource NavDataTemplate} "  HorizontalAlignment ="Right"  VerticalAlignment ="Bottom"  x:Name ="lstNav"   />

        
< TextBlock  x:Name ="txtDebug"  HorizontalAlignment ="Left"  VerticalAlignment ="Top"  Foreground ="White"  Text ="by 菩提树下的杨过"  Margin ="3,3,0,0"  Cursor ="Hand"  MouseLeftButtonDown ="txtDebug_MouseLeftButtonDown"   />

    
</ Grid >
</ UserControl >

后端代码: 

Xaml.cs
using  System;
using  System.Collections.ObjectModel;
using  System.Reflection;
using  System.Windows;
using  System.Windows.Browser;
using  System.Windows.Controls;
using  System.Windows.Threading;
using  System.Windows.Shapes;

namespace  ListBoxSilde
{
    
public   partial   class  MainPage : UserControl
    {
        ObservableCollection
< ImageItem >  _Items;
        
int  _CurrentIndex  =   0 ; // 当前索引号(从0开始)
        DispatcherTimer _timer;


        
public  MainPage()
        {
            InitializeComponent();

            
this .Loaded  +=   new  RoutedEventHandler(MainPage_Loaded);
        }

        
void  MainPage_Loaded( object  sender, RoutedEventArgs e)
        {
            
string  _ArremblyName  =  Assembly.GetExecutingAssembly().FullName.Split( ' , ' )[ 0 ];
            _Items 
=   new  ObservableCollection < ImageItem > ();

            
for  ( int  i  =   1 ; i  <=   4 ; i ++ )
            {
                
string  _img  =   " http://images.24city.com/jimmy/ListBoxSlideShow/img/00 "   +  i.ToString()  +   " .jpg " ;
                _Items.Add(
new  ImageItem() { ImageUri  =  _img, Title  =   " 这是图片00 "   +  i.ToString()  +   " .jpg " , ClickUri  =  _img, Index  =  i });
            }

            
this .lstImage.ItemsSource  =  _Items;
            
this .lstNav.ItemsSource  =  _Items;
            
this .lstNav.SelectedIndex  =  _CurrentIndex;

            _timer 
=   new  DispatcherTimer();
            _timer.Interval 
=   new  System.TimeSpan( 0 0 2 );
            _timer.Tick 
+=   new  System.EventHandler(_timer_Tick);
            _timer.Start();

        }

        
void  _timer_Tick( object  sender, System.EventArgs e)
        {           
            kTo.Value 
=  _CurrentIndex  *   - 480 ;           
            sbMove.Begin();
            lstNav.SelectedIndex 
=  _CurrentIndex;
            _CurrentIndex
++ ;
            
if  (_CurrentIndex  >=  _Items.Count)
            {
                _CurrentIndex 
=   0 ;
            }
        }
       
        
private   void  LayoutRoot_MouseEnter( object  sender, System.Windows.Input.MouseEventArgs e)
        {
            _timer.Stop();
        }

        
private   void  LayoutRoot_MouseLeave( object  sender, System.Windows.Input.MouseEventArgs e)
        {
            _timer.Start();
        }

        
private   void  Image_MouseLeftButtonDown( object  sender, System.Windows.Input.MouseButtonEventArgs e)
        {           
            HtmlPage.Window.Navigate(
new  Uri(_Items[ this .lstNav.SelectedIndex].ClickUri),  " _target " );   
        }

        
private   void  txtDebug_MouseLeftButtonDown( object  sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            HtmlPage.Window.Navigate(
new  Uri( " http://yjmyzz.cnblogs.com/ " ),  " _target " );   
        }

        
private   void  NavItemClick( object  sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            StackPanel g 
=  (sender  as  StackPanel);
            TextBlock txt 
=  g.Children[ 0 as  TextBlock;
            
int  Index  =   int .Parse(txt.Text);            
            kTo.Value 
=  (Index  -   1 *   - 480 ;           
            sbMove.Begin();
            _CurrentIndex 
=  Index  -   1 ;
            lstNav.SelectedIndex 
=  _CurrentIndex;
        }
    }

    
public   class  ImageItem
    {
        
public   string  ImageUri {  set get ; }
        
public   string  Title {  set get ; }
        
public   string  ClickUri {  set get ; }
        
public   int  Index {  set get ; }
    }
}

 

 

作者: 菩提树下的杨过
出处: http://yjmyzz.cnblogs.com/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

你可能感兴趣的:(silverlight)