实现效果

带定时器的轮播图

using引用

using System.Windows;

using System.Windows.Controls;

using System.Windows.Markup;

using System.Windows.Media;

using System.Windows.Media.Animation;

using System.Windows.Threading;

自定义Control

 /// <summary>
/// 轮播控件
/// </summary>
[ContentProperty(nameof(Children))]
public class CarRoundPlay:Control
{ private StackPanel stackPanel; private DispatcherTimer _DtAutoPlay;
static CarRoundPlay()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(CarRoundPlay), new FrameworkPropertyMetadata(typeof(CarRoundPlay)));
}
/// <summary>
/// 构造方法
/// </summary>
public CarRoundPlay()
{
Children = new ObservableCollection<UIElement>();
Loaded += CarRoundPlay_Load;
SizeChanged += CarRoundPlay_Changed;
} /// <summary>
/// 大小发生改变时
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void CarRoundPlay_Changed(object sender, SizeChangedEventArgs e)
{
foreach (FrameworkElement child in Children)
{
child.Width = ActualWidth;
child.Height = ActualHeight;
}
} /// <summary>
/// 控件初始化
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void CarRoundPlay_Load(object sender, RoutedEventArgs e)
{
//判断子集合是否为空
if (Children == null)
return;
//便利子集布局并将当前容器宽高赋予子集布局控件
foreach (FrameworkElement child in Children)
{
child.Width = ActualWidth;
child.Height = ActualHeight;
}
} public override void OnApplyTemplate()
{
base.OnApplyTemplate();
//获取当前显示布局控件
stackPanel = VisualTreeHelper.GetChild(VisualTreeHelper.GetChild(this, 0), 0) as StackPanel;
}
/// <summary>
/// 图片大小发生改变时
/// </summary>
/// <param name="d"></param>
/// <param name="e"></param>
private static void OnIndexChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var carousel = d as CarRoundPlay;
if (!carousel.IsLoaded)
return;
var targetIndex = 0;
if (!carousel.Recyclable)
targetIndex = carousel.Index > (carousel.Children.Count - 1) ? carousel.Children.Count - 1 : (carousel.Index < 0 ? 0 : carousel.Index);
else
targetIndex = carousel.Index > (carousel.Children.Count - 1) ? 0 : (carousel.Index < 0 ? carousel.Children.Count - 1 : carousel.Index); if (targetIndex != carousel.Index)
{
carousel.Index = targetIndex;
return;
}
carousel.ResetAutoPlayTimer();
///判断控件布局触发动画
if (carousel.Orientation == Orientation.Vertical)
{
carousel.stackPanel.BeginAnimation(StackPanel.MarginProperty, new ThicknessAnimation()
{
To = new Thickness(0, -1 * carousel.ActualHeight * carousel.Index, 0, 0),
Duration = carousel.AnimateDuration,
EasingFunction = new CubicEase() { EasingMode = EasingMode.EaseOut }
});
}
else
{
carousel.stackPanel.BeginAnimation(StackPanel.MarginProperty, new ThicknessAnimation()
{
To = new Thickness(-1 * carousel.ActualWidth * carousel.Index, 0, 0, 0),
Duration = carousel.AnimateDuration,
EasingFunction = new CubicEase() { EasingMode = EasingMode.EaseOut }
});
}
carousel.RaiseIndexChanged(targetIndex);
}
private static void OnAutoPlayIntervalChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var carousel = d as CarRoundPlay;
carousel.RestartAutoPlayTimer();
}
/// <summary>
/// 定时切换
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void DispatcherTimerAutoPlay_Tick(object sender, EventArgs e)
{
Index++;
}
public T FindFirstVisualChild<T>(DependencyObject obj, string childName) where T : DependencyObject
{
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
{
DependencyObject child = VisualTreeHelper.GetChild(obj, i);
if (child != null && child is T && child.GetValue(NameProperty).ToString() == childName)
{
return (T)child;
}
else
{
T childOfChild = FindFirstVisualChild<T>(child, childName);
if (childOfChild != null)
{
return childOfChild;
}
}
}
return null;
} #region 公共 /// <summary>
/// 子集合控件
/// </summary>
public ObservableCollection<UIElement> Children
{
get { return (ObservableCollection<UIElement>)GetValue(ChildrenProperty); }
private set { SetValue(ChildrenProperty, value); }
} public static readonly DependencyProperty ChildrenProperty =
DependencyProperty.Register("Children", typeof(ObservableCollection<UIElement>), typeof(CarRoundPlay)); /// <summary>
/// 布局方向
/// </summary>
public Orientation Orientation
{
get { return (Orientation)GetValue( OrientationProperty); }
set { SetValue( OrientationProperty, value); }
} // Using a DependencyProperty as the backing store for Orientation. This enables animation, styling, binding, etc...
public static readonly DependencyProperty OrientationProperty =
DependencyProperty.Register("Orientation", typeof(Orientation), typeof(CarRoundPlay), new PropertyMetadata(Orientation.Horizontal)); /// <summary>
///
/// </summary>
public int Index
{
get { return (int)GetValue(IndexProperty); }
set { SetValue(IndexProperty, value); }
} public static readonly DependencyProperty IndexProperty =
DependencyProperty.Register("Index", typeof(int), typeof(CarRoundPlay), new PropertyMetadata(0, OnIndexChanged)); /// <summary>
/// 动画耗时
/// </summary>
public TimeSpan AnimateDuration
{
get { return (TimeSpan)GetValue(AnimateDurationProperty); }
set { SetValue(AnimateDurationProperty, value); }
} public static readonly DependencyProperty AnimateDurationProperty =
DependencyProperty.Register("AnimateDuration", typeof(TimeSpan), typeof(CarRoundPlay), new PropertyMetadata(TimeSpan.FromSeconds(0.5))); /// <summary>
/// 设置获取
/// </summary>
public bool Recyclable
{
get { return (bool)GetValue(RecyclableProperty); }
set { SetValue(RecyclableProperty, value); }
} public static readonly DependencyProperty RecyclableProperty =
DependencyProperty.Register("Recyclable", typeof(bool), typeof(CarRoundPlay), new PropertyMetadata(false)); /// <summary>
/// 自动动画
/// </summary>
public TimeSpan AutoPlayInterval
{
get { return (TimeSpan)GetValue(AutoPlayIntervalProperty); }
set { SetValue(AutoPlayIntervalProperty, value); }
} public static readonly DependencyProperty AutoPlayIntervalProperty =
DependencyProperty.Register("AutoPlayInterval", typeof(TimeSpan), typeof(CarRoundPlay), new PropertyMetadata(OnAutoPlayIntervalChanged)); #endregion #region RoutedEvent(路由事件)
/// <summary>
/// 轮播index
/// </summary>
public static readonly RoutedEvent IndexChangedEvent = EventManager.RegisterRoutedEvent("IndexChanged", RoutingStrategy.Bubble, typeof(IndexChangedEventHandler), typeof(CarRoundPlay));
public event IndexChangedEventHandler IndexChanged
{
add { AddHandler(IndexChangedEvent, value); }
remove { RemoveHandler(IndexChangedEvent, value); }
}
void RaiseIndexChanged(int newValue)
{
var arg = new IndexChangedEventArgs(newValue, IndexChangedEvent);
RaiseEvent(arg); } #endregion #region Function
private void RestartAutoPlayTimer()
{
if (_DtAutoPlay != null)
{
_DtAutoPlay.Stop();
}
if (AutoPlayInterval.TotalSeconds != 0)
{
_DtAutoPlay = new DispatcherTimer()
{
Interval = AutoPlayInterval,
};
_DtAutoPlay.Tick += DispatcherTimerAutoPlay_Tick;
_DtAutoPlay.Start();
}
} private void ResetAutoPlayTimer()
{
if (_DtAutoPlay != null)
{
_DtAutoPlay.Stop();
_DtAutoPlay.Start();
}
}
#endregion }
   public class IndexChangedEventArgs : RoutedEventArgs
{
public IndexChangedEventArgs(int currentIndex, RoutedEvent routedEvent) : base(routedEvent)
{
CurrentIndex = currentIndex;
} public int CurrentIndex { get; set; }
} public delegate void IndexChangedEventHandler(object sender, IndexChangedEventArgs e);

样式

    <Style TargetType="{x:Type Modules:CarRoundPlay}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Modules:CarRoundPlay}">
<Grid Background="{TemplateBinding Background}"
ClipToBounds="True">
<StackPanel Orientation="{TemplateBinding Orientation}">
<ItemsControl ItemsSource="{TemplateBinding Children}"
VerticalAlignment="Stretch"
HorizontalAlignment="Stretch">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="{Binding Orientation,RelativeSource={RelativeSource AncestorType=Modules:CarRoundPlay}}" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<ContentControl Content="{Binding}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

调用方法

方法一

xmlns:Zt="clr-namespace:RoundPlay.Modules"

  <Grid>
<Zt:CarRoundPlay
BorderBrush="LightGray"
BorderThickness="1" 
Recyclable="True" AutoPlayInterval="0:0:1"
Height="300"
Index="3"
Width="300">
<Grid Background="#F15D26">
<TextBlock VerticalAlignment="Center"
HorizontalAlignment="Center"
Foreground="White"
Text="Page1/44" />
</Grid>
<Grid Background="Beige">
<TextBlock VerticalAlignment="Center"
HorizontalAlignment="Center"
Foreground="White"
Text="Page1/44" />
</Grid>
<Grid Background="Blue">
<TextBlock VerticalAlignment="Center"
HorizontalAlignment="Center"
Foreground="White"
Text="Page1/44" />
</Grid>
</Zt:CarRoundPlay>
</Grid>

方法二

            SolidColorBrush[] brushes = new SolidColorBrush[4] { Brushes.White, Brushes.Red, Brushes.Green, Brushes.Yellow };
Random rnd = new Random();
MainViewModel viewmodel = (this.DataContext as MainViewModel);
for (int i = 0; i < viewmodel.ComWorldLists.Count; i++)
{
Grid grid = new Grid();
int random = rnd.Next(0, brushes.Length - 1);
grid.Background = brushes[random];
TextBlock text = new TextBlock() { HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Center, FontSize = 24, FontWeight = FontWeights.Bold };
text.SetBinding(TextBlock.TextProperty, new Binding($"ComWorldLists[{i}].Name"));
grid.Children.Add(text);
Caruousel.Children.Add(grid);
}

显示效果

WPF自定义控件一:StackPanel 控件轮播的更多相关文章

  1. WPF自定义控件二:Border控件与TextBlock控件轮播动画

    需求:实现Border轮播动画与TextBlock动画 XAML代码如下: <Window.Resources> <Storyboard x:Key="OnLoaded1& ...

  2. WPF自定义控件之图片控件 AsyncImage

    AsyncImage 是一个封装完善,使用简便,功能齐全的WPF图片控件,比直接使用Image相对来说更加方便,但它的内部仍然使用Image承载图像,只不过在其基础上进行了一次完善成熟的封装 Asyn ...

  3. WPF后台设置xaml控件的样式System.Windows.Style

    WPF后台设置xaml控件的样式System.Windows.Style 摘-自 :感谢 作者: IT小兵   http://3w.suchso.com/projecteac-tual/wpf-zhi ...

  4. 在WPF中使用WinForm控件方法

    1.      首先添加对如下两个dll文件的引用:WindowsFormsIntegration.dll,System.Windows.Forms.dll. 2.      在要使用WinForm控 ...

  5. WPF Step By Step 控件介绍

    WPF Step By Step 控件介绍 回顾 上一篇,我们主要讨论了WPF的几个重点的基本知识的介绍,本篇,我们将会简单的介绍几个基本控件的简单用法,本文会举几个项目中的具体的例子,结合这些 例子 ...

  6. 背水一战 Windows 10 (79) - 自定义控件: Layout 系统, 控件模板, 事件处理

    [源码下载] 背水一战 Windows 10 (79) - 自定义控件: Layout 系统, 控件模板, 事件处理 作者:webabcd 介绍背水一战 Windows 10 之 控件(自定义控件) ...

  7. Wpf使用Winform控件后Wpf元素被Winform控件遮盖问题的解决

    有人会说不建议Wpf中使用Winform控件,有人会说建议使用Winform控件在Wpf下的替代方案,然而在实际工作中由于项目的特殊需求,考虑到时间.成本等因素,往往难免会碰到在WPF中使用Winfr ...

  8. WPF自定义选择年月控件详解

    本文实例为大家分享了WPF自定义选择年月控件的具体代码,供大家参考,具体内容如下 封装了一个选择年月的控件,XAML代码: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ...

  9. WPF学习- AllowDrop 用户控件启用拖放功能

    知识点: 创建自定义用户控件(UserControl) 使用户控件成为拖动源 使用户控件成为放置目标 使面板能够接收从用户控件放置的数据 创建项目: 1.新建WPF项目(Wpf-AllowDrop) ...

随机推荐

  1. CentOS-yum安装Redis(单点)

    源文件安装(推荐安装) 在CentOS系统中,首先安装EPEL仓库,然后更新yum源: $ yum install epel-release -y $ yum update -y 然后安装Redis数 ...

  2. Linux:jar服务部署

    1.进入jar包所在文件夹中 2.启动jar,将jar在后台运行,并且记录jar的pid 命令为 : nohup  java  -jar  test.jar (同jar包的配置文件要在jar包同级目录 ...

  3. 学习/etc/group /etc/passwd 和 /etc/shadow

    /etc/passwd 管理用户信息的系统文件 /etc/shadow 管理用户密码信息的系统文件 /etc/group 管理用户组信息的系统文件 1./etc/group 将用户分组是Linux系统 ...

  4. docker安装应用整理

    nginx安装: docker run \ --name nginx \ --volume /var/data/nginx/nginx.conf:/etc/nginx/nginx.conf \ --v ...

  5. c语言:sprintf() 数字转字符赋值给数组

    //sprintf() //sprintf 最常见的应用之一是把整数打印到字符串中,所以,spritnf 在大多数场合可以替代itoa /* 缓冲区溢出 第一个参数的长度太短了,没的说,给个大点的地方 ...

  6. Laravel 6 – 搭建管理后台的用户认证“脚手架”工具

    1. 下载Laravel/ui 命令: composer require laravel/ui "^1.0" -dev 注意laravel framework 6只支持版本1的la ...

  7. P5042 丢失的题面

    P5042 丢失的题面 顺序:10 - 1 - 7 - 8 - 9 - 4 - 5 - 6 - 2 - 3 Point 10 读入,特判,输出. 读入的英文意思是让选手输出自己的程序本身,这个题的确存 ...

  8. Gitlab-500错误的恢复

    一.问题截图 二.定位问题 2.1.查看状态 # 查看状态 gitlab-ctl status # 如图发现gitaly 是down的状态 2.2.查看日志 # 查看日志 gitlab-ctl tai ...

  9. Mac终端美化(iterm2+zsh+oh-my-zsh+powerlevel10k)

    iterm2+zsh+oh-my-zsh+powerlevel10k 一.下载iterm2 方式一:官网下载 https://iterm2.com/ 方式二:百度云下载 链接: https://pan ...

  10. [考试总结]noip模拟26

    首先看到这样中二的题目心头一震.... 然而发现又是没有部分分数的一天. 然而正解不会打.... 那还是得要打暴力. 但是这套题目有两个题目只有一个参数. 所以... (滑稽).jpg 然后我就成功用 ...