带定时器的轮播图
///
[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"
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);
}
手机扫一扫
移动阅读更方便
你可能感兴趣的文章