now you can use ItemsSource on Carousel
This commit is contained in:
1 parent
f4a0c6fd4f
commit
a794c2a2c0
6 files changed
+259
-34
No files matched your search
@@ -9,7 +9,7 @@
|
||||
<Image Width="300" Stretch="UniformToFill" Source="/HandyControlDemo;component/Resources/Img/2.jpg"/>
|
||||
<hc:SimplePanel Width="600">
|
||||
<Image Stretch="UniformToFill" Source="/HandyControlDemo;component/Resources/Img/3.jpg"/>
|
||||
<TextBlock Text="示例文本" Style="{StaticResource TextBlockDefault}" FontSize="100" FontWeight="Bold" Foreground="White"/>
|
||||
<TextBlock Text="Demo Text" Style="{StaticResource TextBlockDefault}" FontSize="100" FontWeight="Bold" Foreground="White"/>
|
||||
</hc:SimplePanel>
|
||||
<Image Width="600" Stretch="UniformToFill" Source="/HandyControlDemo;component/Resources/Img/4.jpg"/>
|
||||
<Image Width="600" Stretch="UniformToFill" Source="/HandyControlDemo;component/Resources/Img/5.jpg"/>
|
||||
|
||||
+158
-19
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.ComponentModel;
|
||||
@@ -21,13 +22,11 @@ namespace HandyControl.Controls
|
||||
[DefaultProperty("Items")]
|
||||
[ContentProperty("Items")]
|
||||
[TemplatePart(Name = ElementPanelPage, Type = typeof(Panel))]
|
||||
[TemplatePart(Name = ElementItemsControl, Type = typeof(ItemsPresenter))]
|
||||
public class Carousel : ListBox, IDisposable
|
||||
public class Carousel : SimpleItemsControl, IDisposable
|
||||
{
|
||||
#region Constants
|
||||
|
||||
private const string ElementPanelPage = "PART_PanelPage";
|
||||
private const string ElementItemsControl = "PART_ItemsControl";
|
||||
|
||||
#endregion Constants
|
||||
|
||||
@@ -39,8 +38,6 @@ namespace HandyControl.Controls
|
||||
|
||||
private bool _appliedTemplate;
|
||||
|
||||
private ItemsPresenter _itemsControl;
|
||||
|
||||
private int _pageIndex = -1;
|
||||
|
||||
private RadioButton _selectedButton;
|
||||
@@ -49,6 +46,12 @@ namespace HandyControl.Controls
|
||||
|
||||
private readonly List<double> _widthList = new List<double>();
|
||||
|
||||
private readonly Dictionary<object, CarouselItem> _entryDic = new Dictionary<object, CarouselItem>();
|
||||
|
||||
private bool _isRefresh;
|
||||
|
||||
private IEnumerable _itemsSourceInternal;
|
||||
|
||||
#endregion Data
|
||||
|
||||
public override void OnApplyTemplate()
|
||||
@@ -59,7 +62,6 @@ namespace HandyControl.Controls
|
||||
|
||||
base.OnApplyTemplate();
|
||||
|
||||
_itemsControl = GetTemplateChild(ElementItemsControl) as ItemsPresenter;
|
||||
_panelPage = GetTemplateChild(ElementPanelPage) as Panel;
|
||||
|
||||
if (!CheckNull()) return;
|
||||
@@ -75,7 +77,7 @@ namespace HandyControl.Controls
|
||||
UpdatePageButtons(_pageIndex);
|
||||
}
|
||||
|
||||
private bool CheckNull() => !(_itemsControl == null || _panelPage == null);
|
||||
private bool CheckNull() => _panelPage != null;
|
||||
|
||||
public static readonly DependencyProperty AutoRunProperty = DependencyProperty.Register(
|
||||
"AutoRun", typeof(bool), typeof(Carousel), new PropertyMetadata(ValueBoxes.FalseBox, (o, args) =>
|
||||
@@ -153,13 +155,6 @@ namespace HandyControl.Controls
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnItemsChanged(NotifyCollectionChangedEventArgs e)
|
||||
{
|
||||
base.OnItemsChanged(e);
|
||||
|
||||
UpdatePageButtons();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否自动跳转
|
||||
/// </summary>
|
||||
@@ -239,14 +234,14 @@ namespace HandyControl.Controls
|
||||
_widthList.Clear();
|
||||
_widthList.Add(0);
|
||||
var width = .0;
|
||||
foreach (FrameworkElement item in Items)
|
||||
foreach (FrameworkElement item in ItemsHost.Children)
|
||||
{
|
||||
item.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
|
||||
width += item.DesiredSize.Width;
|
||||
_widthList.Add(width);
|
||||
}
|
||||
|
||||
_itemsControl.Width = _widthList.Last() + ExtendWidth;
|
||||
ItemsHost.Width = _widthList.Last() + ExtendWidth;
|
||||
_panelPage.Children.Clear();
|
||||
for (var i = 0; i < count; i++)
|
||||
{
|
||||
@@ -278,14 +273,14 @@ namespace HandyControl.Controls
|
||||
if (Items.Count == 0) return;
|
||||
if (!IsCenter)
|
||||
{
|
||||
_itemsControl.BeginAnimation(MarginProperty,
|
||||
ItemsHost.BeginAnimation(MarginProperty,
|
||||
AnimationHelper.CreateAnimation(new Thickness(-_widthList[PageIndex], 0, 0, 0)));
|
||||
}
|
||||
else
|
||||
{
|
||||
var ctl = (FrameworkElement)Items[PageIndex];
|
||||
var ctl = (FrameworkElement)ItemsHost.Children[PageIndex];
|
||||
var ctlWidth = ctl.DesiredSize.Width;
|
||||
_itemsControl.BeginAnimation(MarginProperty,
|
||||
ItemsHost.BeginAnimation(MarginProperty,
|
||||
AnimationHelper.CreateAnimation(
|
||||
new Thickness(-_widthList[PageIndex] + (ActualWidth - ctlWidth) / 2, 0, 0, 0)));
|
||||
}
|
||||
@@ -313,5 +308,149 @@ namespace HandyControl.Controls
|
||||
private void ButtonPrev_OnClick(object sender, RoutedEventArgs e) => PageIndex--;
|
||||
|
||||
private void ButtonNext_OnClick(object sender, RoutedEventArgs e) => PageIndex++;
|
||||
|
||||
protected override DependencyObject GetContainerForItemOverride() => new CarouselItem();
|
||||
|
||||
protected override bool IsItemItsOwnContainerOverride(object item) => item is CarouselItem;
|
||||
|
||||
private void ClearItems()
|
||||
{
|
||||
ItemsHost?.Children.Clear();
|
||||
_entryDic.Clear();
|
||||
}
|
||||
|
||||
private void RemoveItem(object item)
|
||||
{
|
||||
if (_entryDic.TryGetValue(item, out var entry))
|
||||
{
|
||||
ItemsHost.Children.Remove(entry);
|
||||
Items.Remove(item);
|
||||
_entryDic.Remove(item);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void Refresh()
|
||||
{
|
||||
if (ItemsHost == null) return;
|
||||
|
||||
_entryDic.Clear();
|
||||
_isRefresh = true;
|
||||
|
||||
foreach (var item in Items)
|
||||
{
|
||||
AddItem(item);
|
||||
}
|
||||
|
||||
_isRefresh = false;
|
||||
}
|
||||
|
||||
private void AddItem(object item) => InsertItem(_entryDic.Count, item);
|
||||
|
||||
private void InsertItem(int index, object item)
|
||||
{
|
||||
if (ItemsHost == null)
|
||||
{
|
||||
Items.Insert(index, item);
|
||||
_entryDic.Add(item, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
DependencyObject container;
|
||||
if (IsItemItsOwnContainerOverride(item))
|
||||
{
|
||||
container = item as DependencyObject;
|
||||
}
|
||||
else
|
||||
{
|
||||
container = GetContainerForItemOverride();
|
||||
PrepareContainerForItemOverride(container, item);
|
||||
}
|
||||
|
||||
if (container is CarouselItem element)
|
||||
{
|
||||
element.Style = ItemContainerStyle;
|
||||
_entryDic[item] = element;
|
||||
ItemsHost.Children.Insert(index, element);
|
||||
|
||||
if (IsLoaded && !_isRefresh && _itemsSourceInternal != null)
|
||||
{
|
||||
Items.Insert(index, item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnItemsSourceChanged(IEnumerable oldValue, IEnumerable newValue)
|
||||
{
|
||||
if (_itemsSourceInternal != null)
|
||||
{
|
||||
if (_itemsSourceInternal is INotifyCollectionChanged s)
|
||||
{
|
||||
s.CollectionChanged -= InternalCollectionChanged;
|
||||
}
|
||||
|
||||
Items.Clear();
|
||||
ClearItems();
|
||||
}
|
||||
_itemsSourceInternal = newValue;
|
||||
if (_itemsSourceInternal != null)
|
||||
{
|
||||
if (_itemsSourceInternal is INotifyCollectionChanged s)
|
||||
{
|
||||
s.CollectionChanged += InternalCollectionChanged;
|
||||
}
|
||||
foreach (var item in _itemsSourceInternal)
|
||||
{
|
||||
AddItem(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void InternalCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
|
||||
{
|
||||
if (ItemsHost == null) return;
|
||||
|
||||
if (e.Action == NotifyCollectionChangedAction.Reset)
|
||||
{
|
||||
if (_entryDic.Count == 0) return;
|
||||
ClearItems();
|
||||
Items.Clear();
|
||||
return;
|
||||
}
|
||||
|
||||
if (e.OldItems != null)
|
||||
{
|
||||
foreach (var item in e.OldItems)
|
||||
{
|
||||
RemoveItem(item);
|
||||
}
|
||||
}
|
||||
if (e.NewItems != null)
|
||||
{
|
||||
var count = 0;
|
||||
foreach (var item in e.NewItems)
|
||||
{
|
||||
var index = e.NewStartingIndex + count++;
|
||||
InsertItem(index, item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnItemsChanged(object sender, NotifyCollectionChangedEventArgs e)
|
||||
{
|
||||
if (_itemsSourceInternal != null) return;
|
||||
|
||||
InternalCollectionChanged(sender, e);
|
||||
}
|
||||
|
||||
protected override void OnItemTemplateChanged(DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected override void OnItemContainerStyleChanged(DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace HandyControl.Controls
|
||||
{
|
||||
public class CarouselItem : ContentControl
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -76,10 +76,7 @@ namespace HandyControl.Controls
|
||||
{
|
||||
base.OnApplyTemplate();
|
||||
|
||||
if (_viewContent.Style == null)
|
||||
{
|
||||
_viewContent.Style = CoverViewContentStyle;
|
||||
}
|
||||
_viewContent.Style ??= CoverViewContentStyle;
|
||||
|
||||
if (_selectedItem != null)
|
||||
{
|
||||
@@ -181,9 +178,7 @@ namespace HandyControl.Controls
|
||||
}
|
||||
|
||||
_isRefresh = false;
|
||||
|
||||
GenerateIndex();
|
||||
|
||||
UpdateCoverViewContent(_viewContent.IsOpen);
|
||||
}
|
||||
|
||||
@@ -338,10 +333,7 @@ namespace HandyControl.Controls
|
||||
{
|
||||
SetBindingForItem(element);
|
||||
element.Style = ItemContainerStyle;
|
||||
if (element.Header == null)
|
||||
{
|
||||
element.Header = item;
|
||||
}
|
||||
element.Header ??= item;
|
||||
_entryDic[item] = element;
|
||||
ItemsHost.Children.Insert(index, element);
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Controls\Base\AdornerElement.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Controls\Block\FloatingBlock.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Controls\Button\SplitButton.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Controls\Carousel\CarouselItem.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Controls\Growl\GrowlWindow.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Controls\Image\ImageBlock.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Controls\Input\PinBox.cs" />
|
||||
@@ -143,7 +144,7 @@
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Controls\Loading\LoadingLine.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Controls\Other\AnimationPath.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Controls\Other\Badge.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Controls\Other\Carousel.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Controls\Carousel\Carousel.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Controls\Other\ChatBubble.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Controls\ColorPicker\ColorPicker.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Controls\Other\Dialog.cs" />
|
||||
|
||||
@@ -6,10 +6,94 @@
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary Source="../Basic/Paths.xaml"/>
|
||||
<ResourceDictionary Source="Button.xaml"/>
|
||||
<ResourceDictionary Source="ListBox.xaml"/>
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
|
||||
<Style x:Key="CarouselListBoxItemStyle" BasedOn="{StaticResource ListBoxItemCustom}" TargetType="ListBoxItem">
|
||||
<Style x:Key="CarouselItemBaseStyle" TargetType="controls:CarouselItem">
|
||||
<Setter Property="Focusable" Value="False"/>
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="controls:CarouselItem">
|
||||
<Border BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}">
|
||||
<ContentPresenter Margin="{TemplateBinding Padding}" ContentTemplate="{Binding ItemTemplate,RelativeSource={RelativeSource AncestorType=controls:Carousel}}"/>
|
||||
</Border>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="CarouselPateButton" BasedOn="{StaticResource BaseStyle}" TargetType="RadioButton">
|
||||
<Setter Property="Margin" Value="5,0"/>
|
||||
<Setter Property="Width" Value="10"/>
|
||||
<Setter Property="Height" Value="10"/>
|
||||
<Setter Property="Background" Value="White"/>
|
||||
<Setter Property="BorderBrush" Value="{DynamicResource PrimaryBrush}"/>
|
||||
<Setter Property="Padding" Value="0"/>
|
||||
<Setter Property="BorderThickness" Value="1"/>
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="ToggleButton">
|
||||
<Border CornerRadius="5" SnapsToDevicePixels="true" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}" Background="{TemplateBinding Background}"/>
|
||||
<ControlTemplate.Triggers>
|
||||
<Trigger Property="IsMouseOver" Value="True">
|
||||
<Setter Property="Opacity" Value=".9"/>
|
||||
</Trigger>
|
||||
<Trigger Property="IsPressed" Value="True">
|
||||
<Setter Property="Opacity" Value=".6"/>
|
||||
</Trigger>
|
||||
<Trigger Property="IsChecked" Value="True">
|
||||
<Setter Property="Background" Value="{DynamicResource PrimaryBrush}"/>
|
||||
</Trigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style TargetType="controls:Carousel">
|
||||
<Setter Property="PageButtonStyle" Value="{StaticResource CarouselPateButton}"/>
|
||||
<Setter Property="ItemContainerStyle" Value="{StaticResource CarouselItemBaseStyle}"/>
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="controls:Carousel">
|
||||
<ControlTemplate.Triggers>
|
||||
<EventTrigger RoutedEvent="FrameworkElement.MouseEnter">
|
||||
<BeginStoryboard>
|
||||
<Storyboard>
|
||||
<DoubleAnimation Storyboard.TargetName="GridTop" Storyboard.TargetProperty="Opacity" To="1" Duration="0:0:.1"/>
|
||||
</Storyboard>
|
||||
</BeginStoryboard>
|
||||
</EventTrigger>
|
||||
<EventTrigger RoutedEvent="FrameworkElement.MouseLeave">
|
||||
<BeginStoryboard>
|
||||
<Storyboard>
|
||||
<DoubleAnimation Storyboard.TargetName="GridTop" Storyboard.TargetProperty="Opacity" To="0" Duration="0:0:.1"/>
|
||||
</Storyboard>
|
||||
</BeginStoryboard>
|
||||
</EventTrigger>
|
||||
</ControlTemplate.Triggers>
|
||||
<controls:SimplePanel ClipToBounds="True">
|
||||
<StackPanel x:Name="PART_Panel" Orientation="Horizontal"/>
|
||||
<!--<ItemsPresenter x:Name="PART_ItemsControl" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" HorizontalAlignment="Left"/>-->
|
||||
<controls:SimplePanel x:Name="GridTop" Opacity="0">
|
||||
<Button Command="interactivity:ControlCommands.Prev" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="30,0,0,0" Style="{StaticResource ButtonCustom}">
|
||||
<Border Width="50" Height="100" Background="{DynamicResource DarkOpacityBrush}" CornerRadius="4">
|
||||
<Path Margin="16" Fill="White" Style="{StaticResource LeftPathStyle}"/>
|
||||
</Border>
|
||||
</Button>
|
||||
<Button Command="interactivity:ControlCommands.Next" HorizontalAlignment="Right" VerticalAlignment="Center" Margin="0,0,30,0" Style="{StaticResource ButtonCustom}">
|
||||
<Border Width="50" Height="100" Background="{DynamicResource DarkOpacityBrush}" CornerRadius="4">
|
||||
<Path Margin="16" Fill="White" Style="{StaticResource RightPathStyle}"/>
|
||||
</Border>
|
||||
</Button>
|
||||
</controls:SimplePanel>
|
||||
<StackPanel Name="PART_PanelPage" Orientation="Horizontal" VerticalAlignment="Bottom" HorizontalAlignment="Center" Margin="0,0,0,20"/>
|
||||
</controls:SimplePanel>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<!--<Style x:Key="CarouselListBoxItemStyle" BasedOn="{StaticResource ListBoxItemCustom}" TargetType="ListBoxItem">
|
||||
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
|
||||
<Setter Property="VerticalContentAlignment" Value="Stretch"/>
|
||||
<Setter Property="Height" Value="{Binding ActualHeight, RelativeSource={RelativeSource AncestorType=ItemsControl}}"/>
|
||||
@@ -92,6 +176,6 @@
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
</Style>-->
|
||||
|
||||
</ResourceDictionary>
|
||||
Reference in new issue
Block a user