blob: b120bd3e34f02868b8b62017517d5356d5a0e4af (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
|
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Markup;
using System.Windows.Media;
namespace MaterialDesignThemes.Wpf.Transitions
{
/// <summary>
/// Multiplies a time span unit by the index of an item in a list.
/// </summary>
/// <remarks>
/// Example usage is for a <see cref="TransitioningContent"/> to have a <see cref="TransitionEffect.OffsetTime" />
/// time delayed according to position in a list, so cascading animations can occur.
/// </remarks>
[MarkupExtensionReturnType(typeof(TimeSpan))]
public class IndexedItemOffsetMultiplierExtension : MarkupExtension
{
public IndexedItemOffsetMultiplierExtension(TimeSpan unit)
{
Unit = unit;
}
[ConstructorArgument("unit")]
public TimeSpan Unit { get; set; }
public override object ProvideValue(IServiceProvider serviceProvider)
{
var provideValueTarget = serviceProvider.GetService(typeof(IProvideValueTarget)) as IProvideValueTarget;
if (provideValueTarget == null) return TimeSpan.Zero;
if (provideValueTarget.TargetObject != null &&
provideValueTarget.TargetObject.GetType().FullName == "System.Windows.SharedDp")
//we are inside a template, return this, so we can re-evaluate later...
return this;
var element = provideValueTarget?.TargetObject as DependencyObject;
if (element == null) return TimeSpan.Zero;
var itemsControl = ItemsControl.ItemsControlFromItemContainer(element);
if (itemsControl == null)
{
var ancestor = element;
while (ancestor != null && itemsControl == null)
{
ancestor = VisualTreeHelper.GetParent(ancestor);
itemsControl = ItemsControl.ItemsControlFromItemContainer(ancestor);
}
}
if (itemsControl == null) return TimeSpan.Zero;
var isOwnContainer = itemsControl.IsItemItsOwnContainer(element);
var container = isOwnContainer
? element
: itemsControl.ItemContainerGenerator.ContainerFromItem(element);
if (container == null)
{
var dataContext = (element as FrameworkElement)?.DataContext;
if (dataContext != null)
container = itemsControl.ItemContainerGenerator.ContainerFromItem(dataContext);
}
if (container == null) return TimeSpan.Zero;
var multiplier = itemsControl.ItemContainerGenerator.IndexFromContainer(container);
if (multiplier == -1) //container generation may not have completed
{
multiplier = itemsControl.Items.IndexOf(element);
}
if (multiplier == -1) //still not found, repeat now using datacontext
{
var frameworkElement = element as FrameworkElement;
if (frameworkElement != null)
{
multiplier = itemsControl.Items.IndexOf(frameworkElement.DataContext);
}
}
return multiplier > -1 ? new TimeSpan(Unit.Ticks * multiplier) : TimeSpan.Zero;
}
}
}
|