feat: add demo page, prepare collection changed behavior.
This commit is contained in:
@@ -1,6 +1,11 @@
|
||||
using System.Collections.Specialized;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices.ComTypes;
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Controls.Generators;
|
||||
using Avalonia.Controls.Presenters;
|
||||
using Avalonia.Controls.Primitives;
|
||||
using Avalonia.Controls.Templates;
|
||||
|
||||
namespace Ursa.Controls;
|
||||
@@ -17,33 +22,33 @@ public class Timeline: ItemsControl
|
||||
set => SetValue(ItemDescriptionTemplateProperty, value);
|
||||
}
|
||||
|
||||
protected override bool IsItemItsOwnContainerOverride(Control item)
|
||||
public Timeline()
|
||||
{
|
||||
return item is TimelineItem;
|
||||
ItemsView.CollectionChanged+=ItemsViewOnCollectionChanged;
|
||||
}
|
||||
|
||||
protected override Control CreateContainerForItemOverride()
|
||||
private void ItemsViewOnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
|
||||
{
|
||||
return new TimelineItem();
|
||||
RefreshTimelineItems();
|
||||
}
|
||||
|
||||
protected override void PrepareContainerForItemOverride(Control container, object? item, int index)
|
||||
|
||||
protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
|
||||
{
|
||||
base.PrepareContainerForItemOverride(container, item, index);
|
||||
if (container is TimelineItem c )
|
||||
base.OnPropertyChanged(change);
|
||||
RefreshTimelineItems();
|
||||
}
|
||||
|
||||
private void RefreshTimelineItems()
|
||||
{
|
||||
for (int i = 0; i < this.LogicalChildren.Count; i++)
|
||||
{
|
||||
if (item is ITimelineItemData data)
|
||||
if (this.LogicalChildren[i] is TimelineItem t)
|
||||
{
|
||||
c[TimelineItem.TimeProperty] = data;
|
||||
c[ContentControl.ContentProperty] = data.Content;
|
||||
c[TimelineItem.DescriptionProperty] = data.Description;
|
||||
if(ItemTemplate is {}) c[ContentControl.ContentTemplateProperty] = this.ItemTemplate;
|
||||
if(ItemDescriptionTemplate is {}) c[TimelineItem.DescriptionTemplateProperty] = this.ItemDescriptionTemplate;
|
||||
t.SetPosition(i == 0, i == this.LogicalChildren.Count - 1);
|
||||
}
|
||||
else
|
||||
else if (this.LogicalChildren[i] is ContentPresenter { Child: TimelineItem t2 })
|
||||
{
|
||||
c.Content = item;
|
||||
if (ItemTemplate is { }) c[ContentControl.ContentTemplateProperty] = this.ItemTemplate;
|
||||
t2.SetPosition(i == 0, i == this.LogicalChildren.Count - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
17
src/Ursa/Controls/Timeline/TimelineFormatConverter.cs
Normal file
17
src/Ursa/Controls/Timeline/TimelineFormatConverter.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
using System.Globalization;
|
||||
using Avalonia;
|
||||
using Avalonia.Data.Converters;
|
||||
|
||||
namespace Ursa.Controls;
|
||||
|
||||
public class TimelineFormatConverter: IMultiValueConverter
|
||||
{
|
||||
public object? Convert(IList<object?> values, Type targetType, object? parameter, CultureInfo culture)
|
||||
{
|
||||
if (values.Count> 1 && values[0] is DateTime date && values[1] is string s)
|
||||
{
|
||||
return date.ToString(s, culture);
|
||||
}
|
||||
return AvaloniaProperty.UnsetValue;
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
using System.Globalization;
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Controls.Metadata;
|
||||
@@ -12,7 +13,7 @@ public class TimelineItem: ContentControl
|
||||
{
|
||||
public const string PC_First = ":first";
|
||||
public const string PC_Last = ":last";
|
||||
|
||||
|
||||
public static readonly StyledProperty<IBrush> IconForegroundProperty =
|
||||
AvaloniaProperty.Register<TimelineItem, IBrush>(nameof(IconForeground));
|
||||
|
||||
@@ -40,7 +41,7 @@ public class TimelineItem: ContentControl
|
||||
}
|
||||
|
||||
public static readonly StyledProperty<string?> TimeFormatProperty = AvaloniaProperty.Register<TimelineItem, string?>(
|
||||
nameof(TimeFormat));
|
||||
nameof(TimeFormat), defaultValue:CultureInfo.CurrentUICulture.DateTimeFormat.SortableDateTimePattern);
|
||||
|
||||
public string? TimeFormat
|
||||
{
|
||||
@@ -56,4 +57,10 @@ public class TimelineItem: ContentControl
|
||||
get => GetValue(DescriptionTemplateProperty);
|
||||
set => SetValue(DescriptionTemplateProperty, value);
|
||||
}
|
||||
|
||||
internal void SetPosition(bool isFirst, bool isLast)
|
||||
{
|
||||
PseudoClasses.Set(PC_First, isFirst);
|
||||
PseudoClasses.Set(PC_Last, isLast);
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
namespace Ursa.Controls;
|
||||
|
||||
public interface ITimelineItemData
|
||||
{
|
||||
public DateTime Time { get; set; }
|
||||
public object Content { get; set; }
|
||||
public object Description { get; set; }
|
||||
public TimelineItemType ItemType { get; set; }
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
namespace Ursa.Controls;
|
||||
|
||||
/// <summary>
|
||||
/// Describe how TimelineItem components should be placed around the line.
|
||||
/// </summary>
|
||||
public enum TimelinePlacement
|
||||
{
|
||||
Left,
|
||||
Right,
|
||||
Center,
|
||||
Alternate,
|
||||
}
|
||||
Reference in New Issue
Block a user