开发者社区> 杨俊明> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

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

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

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

运行后的样子类似这样:


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

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

xaml代码:

img_405b18b4b6584ae338e0f6ecaf736533.gif代码
<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(002);
            _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[0as 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 { setget; }
        
public string Title { setget; }
        
public string ClickUri { setget; }
        
public int Index { setget; }
    }
}

 

 

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
asp.net 图片批量上传预览,在Silverlight页面中读取并滚动显示
Silverlight动态读取图片并滚动显示 asp.net页面中图片上传并预览   ...
590 0
[Silverlight]使用WritableBitmap将图片处理成为黑白图片
原文 http://www.dotblogs.com.tw/junegoat/archive/2010/10/02/silverlight-black-and-white.aspx 之前遇到我们家设计一个小要求.
750 0
CSLA .NET 3.6支持Silverlight 2
作者 Abel Avram   译者 霍泰稳     .NET平台上基于组件的可扩展逻辑架构(CSLA .NET)发布了3.6版本,其中包括了对微软Silverlight 2 的支持。CSLA .NET是一个.NET软件开发框架,帮助开发者“为Windows、Web、面向服务和工作流等应用构建强大和可维护的业务逻辑层”。
975 0
silverlight beet - 从xap文件中加载图片
xaml写法: c#写法: xImage.Source = new BitmapImage(new Uri("/pic;component/img.jpg", UriKind.Relative)); 其中"/{0};component/{1}"0为xap程序集的名字 1为tup在xap中的路径.
556 0
一起谈.NET技术,Silverlight面向客户端,HTML5面向Web
  Bob Muglia在PDC 2010讲到Silverlight的时候,说“我们的策略已经转移了”,事后,他又试图澄清这到底是什么意思。Steve Ballmer和Tim Heuer也对Silverlight发表评论,试图重新让社区确信微软对Silverlight的承诺,但是他们也指出这样的事实,HTML5是针对跨平台开发的解决方案,而Silverlight针对的是客户端和Windows Phone。
935 0
一起谈.NET技术,Silverlight 的多线程能力(下)
  上一期笔者介绍了Silverlight实现多线程的诸多解决方案,本期笔者将通过一个实例来实现所有多线程编程方法,并且还将于JavaScript和Flash两种Web客户端技术性能进行比较,请勿拍砖。
753 0
+关注
杨俊明
菩提树下的杨过 http://yjmyzz.cnblogs.com/
1102
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载
冬季实战营第三期:MySQL数据库进阶实战
立即下载