原文:
有前面修改按钮样式的基础,我们可以尝试来定制一个即好看又好用的 ListBox ,今天先来讲“好看”部分。
打开 Microsoft Visual Studio 2008 ,建立一个WPF应用程序,调整窗体大小,在窗体内创建一个 ListBox 和一个 Button ,按下图所示布局。
在 Window1.xaml 中为窗体 Loaded 事件及按钮 Click 事件添加事件处理:
Code <Window x:Class="自定义列表项.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Window1" Height="351" Width="416" Loaded="Window_Loaded"> <Grid> <ListBox Margin="26,21,27,54" Name="listBox1" /> <Button Height="23" Click="button1_Click" Margin="26,0,0,13" Name="button1" VerticalAlignment="Bottom" HorizontalAlignment="Left" Width="75" Background="AliceBlue">选择文件</Button> </Grid></Window>
在项目的引用中添加对 System.Windows.Froms 的引用,因为我们要使用其中的“打开文件对话框”组件。
添加 using 语句,引用以下所示的命名空间。为 System.Windows.Froms 设置别名是为了防止和现有的命名空间内的名称冲突。
在 Window1.xaml.cs 中书写以下代码:
Code using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Windows;using System.Windows.Controls;using System.Windows.Data;using System.Windows.Documents;using System.Windows.Input;using System.Windows.Media;using System.Windows.Media.Imaging;using System.Windows.Navigation;using System.Windows.Shapes;using System.IO;using System.Collections.ObjectModel;using Forms=System.Windows.Forms;namespace 自定义列表项{ /**//// <summary> /// Window1.xaml 的交互逻辑 /// </summary> public partial class Window1 : Window { public Window1() { InitializeComponent(); } public ObservableCollection<FileInfo> FileList=new ObservableCollection<FileInfo>(); private void Window_Loaded(object sender, RoutedEventArgs e) { listBox1.ItemsSource = FileList; } private void button1_Click(object sender, RoutedEventArgs e) { var open=new Forms.OpenFileDialog { Multiselect = true }; if (open.ShowDialog() == Forms.DialogResult.OK) { foreach (string f in open.FileNames) FileList.Add(new FileInfo(f)); } } }}
我们采用泛型集合 ObservableCollection<FileInfo> 装载文件列表,ObservableCollection 不同于以往的集合类型,它会在其内容更改时向 WPF 控件发送更新通知,以确保显示和数据的同步,所以 WPF 开发中,集合类型应多使用该类型。
在窗体载入完毕后,将 ListBox1 绑定到文件列表 FileList 。
这时编译并运行程序,选择一些文件,应当是这个样子:
在App.xaml中添加如下样式设定:
Code <!--ListBox样式--> <Style TargetType="ListBox"> <Setter Property="BorderBrush" Value="#BDD4F1"/> <Setter Property="BorderThickness" Value="1"/> <Setter Property="Background" Value="#F8F7F5"/> <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Hidden"/> <Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/> <Setter Property="ScrollViewer.CanContentScroll" Value="true"/> <Setter Property="VerticalContentAlignment" Value="Center"/> </Style> <!--ListBoxItem样式--> <Style TargetType="ListBoxItem"> <Setter Property="Foreground" Value="#B5BABF"/> <Setter Property="OverridesDefaultStyle" Value="True"/> <Setter Property="Height" Value="24"/> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="ListBoxItem"> <Border Name="back" BorderBrush="#F8F7F5" BorderThickness="0,1,0,1"> <Border.Background> <LinearGradientBrush StartPoint="0,0" EndPoint="0,1"> <GradientBrush.GradientStops> <GradientStopCollection> <GradientStop Color="#F8F7F5" Offset="0.0"/> <GradientStop Color="#F8F7F5" Offset="0.5"/> <GradientStop Color="#F8F7F5" Offset="0.51"/> <GradientStop Color="#F8F7F5" Offset="1"/> </GradientStopCollection> </GradientBrush.GradientStops> </LinearGradientBrush> </Border.Background> <ContentPresenter Margin="2" VerticalAlignment="Center"/> </Border> <ControlTemplate.Triggers> <Trigger Property="IsSelected" Value="True"> <Trigger.EnterActions> <BeginStoryboard> <Storyboard> <DoubleAnimation To="32" Duration="0:0:0.3" Storyboard.TargetProperty="Height"/> <ColorAnimation To="#F3C37C" Duration="0:0:0.2" Storyboard.TargetName="back" Storyboard.TargetProperty="(Border.BorderBrush).(SolidColorBrush.Color)" /> <ColorAnimation To="#952B00" Duration="0:0:0.2" Storyboard.TargetProperty="(ListBoxItem.Foreground).(SolidColorBrush.Color)" /> <ColorAnimation To="#FFF" Duration="0:0:0.2" Storyboard.TargetName="back" Storyboard.TargetProperty="(Border.Background).(LinearGradientBrush.GradientStops)[0].(GradientStop.Color)" /> <ColorAnimation To="#FFEF99" Duration="0:0:0.2" Storyboard.TargetName="back" Storyboard.TargetProperty="(Border.Background).(LinearGradientBrush.GradientStops)[1].(GradientStop.Color)" /> <ColorAnimation To="#FFE13F" Duration="0:0:0.2" Storyboard.TargetName="back" Storyboard.TargetProperty="(Border.Background).(LinearGradientBrush.GradientStops)[2].(GradientStop.Color)" /> <ColorAnimation To="#FFF3B0" Duration="0:0:0.2" Storyboard.TargetName="back" Storyboard.TargetProperty="(Border.Background).(LinearGradientBrush.GradientStops)[3].(GradientStop.Color)" /> </Storyboard> </BeginStoryboard> </Trigger.EnterActions> <Trigger.ExitActions> <BeginStoryboard> <Storyboard> <DoubleAnimation BeginTime="0:0:0.4" Duration="0:0:0.2" Storyboard.TargetProperty="Height"/> <ColorAnimation Duration="0:0:0.2" Storyboard.TargetName="back" Storyboard.TargetProperty="(Border.BorderBrush).(SolidColorBrush.Color)" /> <ColorAnimation Duration="0:0:0.2" Storyboard.TargetProperty="(ListBoxItem.Foreground).(SolidColorBrush.Color)" /> <ColorAnimation Duration="0:0:0.2" Storyboard.TargetName="back" Storyboard.TargetProperty="(Border.Background).(LinearGradientBrush.GradientStops)[0].(GradientStop.Color)" /> <ColorAnimation Duration="0:0:0.2" Storyboard.TargetName="back" Storyboard.TargetProperty="(Border.Background).(LinearGradientBrush.GradientStops)[1].(GradientStop.Color)" /> <ColorAnimation Duration="0:0:0.2" Storyboard.TargetName="back" Storyboard.TargetProperty="(Border.Background).(LinearGradientBrush.GradientStops)[2].(GradientStop.Color)" /> <ColorAnimation Duration="0:0:0.2" Storyboard.TargetName="back" Storyboard.TargetProperty="(Border.Background).(LinearGradientBrush.GradientStops)[3].(GradientStop.Color)" /> </Storyboard> </BeginStoryboard> </Trigger.ExitActions> </Trigger> <Trigger Property="IsMouseOver" Value="True"> <Trigger.EnterActions> <BeginStoryboard> <Storyboard> <ColorAnimation To="#D8E6F5" Duration="0:0:0.2" Storyboard.TargetName="back" Storyboard.TargetProperty="(Border.BorderBrush).(SolidColorBrush.Color)" /> <ColorAnimation To="#617A98" Duration="0:0:0.2" Storyboard.TargetProperty="(ListBoxItem.Foreground).(SolidColorBrush.Color)" /> <ColorAnimation To="#F6F9FD" Duration="0:0:0.2" Storyboard.TargetName="back" Storyboard.TargetProperty="(Border.Background).(LinearGradientBrush.GradientStops)[0].(GradientStop.Color)" /> <ColorAnimation To="#E0EBF7" Duration="0:0:0.2" Storyboard.TargetName="back" Storyboard.TargetProperty="(Border.Background).(LinearGradientBrush.GradientStops)[1].(GradientStop.Color)" /> <ColorAnimation To="#D7E5F6" Duration="0:0:0.2" Storyboard.TargetName="back" Storyboard.TargetProperty="(Border.Background).(LinearGradientBrush.GradientStops)[2].(GradientStop.Color)" /> <ColorAnimation To="#F6F9FD" Duration="0:0:0.2" Storyboard.TargetName="back" Storyboard.TargetProperty="(Border.Background).(LinearGradientBrush.GradientStops)[3].(GradientStop.Color)" /> </Storyboard> </BeginStoryboard> </Trigger.EnterActions> <Trigger.ExitActions> <BeginStoryboard> <Storyboard> <ColorAnimation Duration="0:0:0.2" Storyboard.TargetName="back" Storyboard.TargetProperty="(Border.BorderBrush).(SolidColorBrush.Color)" /> <ColorAnimation Duration="0:0:0.2" Storyboard.TargetProperty="(ListBoxItem.Foreground).(SolidColorBrush.Color)" /> <ColorAnimation Duration="0:0:0.2" Storyboard.TargetName="back" Storyboard.TargetProperty="(Border.Background).(LinearGradientBrush.GradientStops)[0].(GradientStop.Color)" /> <ColorAnimation Duration="0:0:0.2" Storyboard.TargetName="back" Storyboard.TargetProperty="(Border.Background).(LinearGradientBrush.GradientStops)[1].(GradientStop.Color)" /> <ColorAnimation Duration="0:0:0.2" Storyboard.TargetName="back" Storyboard.TargetProperty="(Border.Background).(LinearGradientBrush.GradientStops)[2].(GradientStop.Color)" /> <ColorAnimation Duration="0:0:0.2" Storyboard.TargetName="back" Storyboard.TargetProperty="(Border.Background).(LinearGradientBrush.GradientStops)[3].(GradientStop.Color)" /> </Storyboard> </BeginStoryboard> </Trigger.ExitActions> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style>
最终效果(按钮是沿用以前教程制作的样式):
样式代码部分基本没什么可讲的了,看看前面的教程应该都可以搞明白了,有不懂的地方请留言发问吧。
这次教程主要是为了后面做铺垫,在下一篇教程中,我将会为大家讲述如何定制列表项的内容,比如让每个项目都可以显示图片、文件尺寸等信息,借助 WPF 的强大界面设计特性,我们不需开发自定义控件,只需用一些 XAML 代码,就可以为普通控件赋予丰富的呈现功能,敬请关注。