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; }
    }
}

 

 

时间: 2024-09-07 18:14:50

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

silverlight版的图片轮换广告

今天下午模仿公司的Flash版图片广告做了一个silverlight版的图片轮换广告,10秒轮换一次 xaml代码: xaml 1<UserControl 2    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4    x:Class="Ad.P

JavaScript 学习笔记之一jQuery写法图片等比缩放以及预加载_jquery

JavaScript 学习笔记之一jQuery写法图片等比缩放以及预加载 以前对于JavaScript总是在用到的时候在页面上写几个函数,基本没考虑到函数的封装与重用,最近有个项目可能对于这方面要求有点高,所以就研究了下类似jQuery的封装. 这里就图片等比缩放以及预加载的效果来尝试下,写写类似的JavaScript代码. 图片等比缩放以及预加载的效果如下(预加载效果有时候会不是很明显): JS主要代码如下: 复制代码 代码如下: (function() { var yQuery = (fun

Silverlight项目中&quot;自定义控件开发/Style&quot;学习笔记

本文不涉及高深的设计模式(比如mvc,mvvm之类),也没有太多的编程技巧,只是记录自己做为asp.net开发者学习silverlight中自定义控件开发的一些过程,高手请绕过.  先推荐一篇不错的文章http://www.cnblogs.com/carysun/articles/1259025.html 写得很全面,只不过图片讲解不够丰富,初学者可能有些感到跳跃性大了一些.  正文开始:  做过asp.net网站开发的都知道用户控件是一个很方便的功能,通常我们会把一些模块化的功能封装成用户控件

Silverlight Telerik控件学习:RadTransitionControl

如果展示类似这种比较cool的图片轮换效果,用RadTransitionControl控件就对了,它提供的过渡效果非常cool! 原理并不复杂,可参见以前写的 Silverlight之ListBox/Style学习笔记--ListBox版的图片轮换广告. xaml部分: <UserControl xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation" x:Class="Telerik.Sampl

Flash/Flex学习笔记(52):使用TweenLite

TweenLite是第三方出品的专用于各种缓动动画的类库,其性能据说已经超过了Adobe官方的Tween. 从网上找到了一篇中文的说明文档:http://files.cnblogs.com/yjmyzz/tweenLite%e4%b8%ad%e6%96%87%e6%89%8b%e5%86%8c%e4%b8%8e%e5%8f%82%e6%95%b0%e8%af%b4%e6%98%8e.pdf 这是官方的测试示例: AS3类库下载: http://files.cnblogs.com/yjmyzz/g

Symbian学习笔记

Symbian学习笔记(22) - 关于皮肤的小结 Symbian学习笔记(21)--原来还有这个工具wsdl2cpp,访问webserv Symbian学习笔记(20)--用gSOAP更简单地实现Web Services Clien Symbian学习笔记(19)--初探WebServices API的使用(下) Symbian学习笔记(18)--初探WebServices API的使用(中) Symbian学习笔记(17)--初探WebServices API的使用(上) Symbian学习

WPF and Silverlight学习笔记(二十五)

WPF and Silverlight学习笔记(二十五):使用CollectionView实现对绑定数据的排序.筛选.分组 在第二十三节,我们使用CollectionView实现了对于绑定数据的导航,除导 航功能外,还可以通过CollectionView对数据进行类似于DataView的排序.筛选 等功能. 一.数据的排序: 使用第二十四节的数据源,查询所有 的产品信息: 1: <Window x:Class="WPF_24.CollectionViewSortData" 2:

WPF + Silverlight学习笔记

WPF and Silverlight学习笔记(三十):Brush(2) WPF and Silverlight学习笔记(二十九):Brush(1) WPF and Silverlight学习笔记(二十八):基本图形的使用(3)图 WPF and Silverlight学习笔记(二十七):基本图形的使用(2)Pa WPF and Silverlight学习笔记(二十六):基本图形使用(1) WPF and Silverlight学习笔记(二十五) WPF and Silverlight学习笔记(

WPF and Silverlight学习笔记(十二)

WPF and Silverlight学习笔记(十二):WPF Panel内容模型.Decorator内容模型及其他 一.Panel内容模型 Panel内容模型指从 System.Windows.Controls.Panel继承的控件,这些控件都是容器,可以在内部 承载其他的控件和子容器.Panel内容模型包含的容器有: Canvas DockPanel Grid TabPanel ToolBarO verflowPanel UniformGrid StackPanel ToolBarPanel