自定义WPF轮播控件





5.00/5 (31投票s)
本文介绍了一个简单的WPF轮播控件。
引言
走马灯控件是一种强大且视觉上吸引人的方式来呈现多个数据项。不幸的是,Microsoft没有提供现成的实现。有很多免费可用的走马灯控件。
两个最著名的免费走马灯控件可以说是:
- https://codeproject.org.cn/Articles/181835/WPF-Carousel-Control
- https://archive.codeplex.com/?p=wpfcarousel
最初,我尝试使用第一个版本,并将其调整到我们自己的需求。不幸的是,它基于Microsoft的PathListBox控件,从而隐藏了大部分实现细节。我发现很难修改它以适应我们的需求,最终放弃了。
第二个走马灯是一个很好的简单实现,但是作者将球体硬编码为走马灯项,并且他未公开任何依赖属性,这限制了它的实用性。
我决定使用第二个走马灯作为起点来创建一个更灵活的走马灯控件。
本文包含新的WPF走马灯控件的源代码和一个简单的演示应用程序。
背景
您需要很好地理解C#以及WPF的基础知识。
概述
走马灯控件可以水平排列项目

它也可以垂直排列项目

我称之为WPFCarouselControl的新走马灯控件(恐怕原创性方面没有加分)具有以下依赖属性:
| 
 | 走马灯项目显示的数据。 | 
| SelectedItem | 当前选定的项目。 | 
| CarouselItemTemplate | 定义每个走马灯项的外观和行为。 | 
| AutoSizeToParent | 如果为 true,则控件会调整自身大小以适应可用空间。 | 
| TiltInDegrees | 项目似乎围绕其旋转的轴的倾斜角度。 | 
| RotationSpeed | 选择新项目时项目旋转的速度。 | 
| 淡入淡出 | 一个介于 0和1之间的值,用于确定项目的不透明度如何随位置而变化。离选定项目最远的项目具有最低的不透明度。 | 
| Scale | 应用于走马灯中项目的缩放比例,以创建3D效果。值为1表示所有项目具有相同的大小。小于1的值会创建透视效果。范围为 0到1(包含)。 | 
| VerticalOrientation | 如果为 true,则项目垂直排列;如果为false,则项目水平排列。 | 
使用WPFCarouselControl
在应用程序中使用该控件很简单。
首先,创建一个类来存储在一个走马灯项目中显示的数据。例如:
    public class RadioStation
    {
        public string Name { get; set; }
        public string ShortName { get; set; }
        public string ImageSource { get; set; }
        public string Text { get; set; }
    }
接下来,将CarouselControl添加到您的视图中。例如:
<WPFCarouselControl:CarouselControl Grid.Row="5" Grid.Column="1" 
Grid.ColumnSpan="5" x:Name="_carouselDABRadioStations" 
ItemsSource="{Binding RadioStationsDAB}" 
SelectedItem="{Binding SelectedRadioStationDAB,Mode=TwoWay}" 
ShowRotation="True"  TiltInDegrees="10" 
AutoSizeToParent="true" RotationSpeed="100" 
VerticalOrientation="False" HorizontalAlignment="Stretch" 
VerticalAlignment="Stretch">
    <WPFCarouselControl:CarouselControl.Style>
        <Style TargetType="WPFCarouselControl:CarouselControl">
            <Setter Property="CarouselItemTemplate" >
                <Setter.Value>
                    <ControlTemplate>
                        <Border BorderThickness="1" 
                        BorderBrush="Gainsboro" Background="SteelBlue" 
                        Width="250" Height="150">
                            <Grid>
                                <Grid.RowDefinitions>
                                    <RowDefinition Height="*"/>
                                    <RowDefinition Height="30"/>
                                </Grid.RowDefinitions>
                                <Border Grid.Row="0" 
                                BorderThickness="0" Background="White">
                                    <Image Grid.Row="0" 
                                    Source="{Binding ImageSource}" 
                                    VerticalAlignment="Center" 
                                    HorizontalAlignment="Center" Height="100"/>
                                </Border>
                                <Label Grid.Row="1" 
                                Content="{Binding ShortName}" 
                                Foreground="White" Background="Transparent" 
                                FontSize="20" FontFamily="Arial" 
                                Style="{StaticResource labelStyleCentred}" 
                                DockPanel.Dock="Bottom" Height="Auto"/>
                            </Grid>
                        </Border>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </WPFCarouselControl:CarouselControl.Style>
</WPFCarouselControl:CarouselControl>
请注意CarouselItemTemplate属性,它定义了一个由包含图像和文本行的矩形组成的走马灯项目。
ItemsSource属性绑定到在视图模型中定义的RadioStationsDAB属性,如下所示:
private System.Collections.ObjectModel.ObservableCollection
                              <Model.RadioStation> _radioStationsDAB;
public System.Collections.ObjectModel.ObservableCollection
                              <Model.RadioStation> RadioStationsDAB
{
    get
    {
        return _radioStationsDAB;
    }
    set
    {
        _radioStationsDAB = value;
        NotifyPropertyChanged("RadioStationsDAB");
    }
}
实现细节
WPF走马灯控件是一个包含Canvas控件的WPF用户控件。
项目控件是canvas的子元素,布置在投影到屏幕平面上的圆圈上。
该控件实现了一个SelectionChanged事件,允许所有者在通过鼠标左键单击选择项目时接收通知。
旋转是使用计时器实现的,该计时器在选定项目更改时启动。计时器每10毫秒触发一次,以确保平滑旋转。在每次滴答时,它都会将项目移动与旋转速度成比例的量。
添加/删除项目
ItemsSource属性假定它绑定到实现System.Collections.IEnumerable和System.Collections.Specialized.INotifyCollectionChanged接口的集合对象。如果从项目列表中添加和/或删除项目,则必须实现后者接口。
限制
当前控件在虚构的圆圈周围均匀地布置项目。如果您想更改布局,则需要编辑SetElementPositions方法。如果您感觉有冒险精神,您可以沿着Path依赖属性布置项目。
历史
- 2019年5月9日:版本1
- 2019年5月9日:版本2:实现了CarouselItemTemplate依赖属性
- 2019年11月5日:版本3:修复了旋转算法中的一个错误,该错误导致旋转方向意外反转。下载代码已更新。
- 2019年11月21日:版本4:更新了ItemsSource属性,以允许添加和/或删除项目。
- 2019年11月22日:版本5:修复了布局,以便选定项目现在始终位于中心。


