comparison MetroWpf/MetroWpf.Xaml/Transitions/TransitionPresenter.cs @ 24:a8b50a087544

Stocks and FxRates working, new menu introduced. Working nicely so far
author adminsh@apollo
date Tue, 20 Mar 2012 20:18:35 +0000
parents
children
comparison
equal deleted inserted replaced
23:399398841fd0 24:a8b50a087544
1 using System;
2 using System.Windows;
3 using System.Windows.Controls;
4 using System.Windows.Documents;
5 using System.Windows.Media;
6
7 namespace MetroWpf.Xaml.Transitions
8 {
9 [System.Windows.Markup.ContentProperty("Content")]
10 public class TransitionPresenter : FrameworkElement
11 {
12 static TransitionPresenter()
13 {
14 ClipToBoundsProperty.OverrideMetadata(typeof(TransitionPresenter), new FrameworkPropertyMetadata(null, CoerceClipToBounds));
15 }
16
17 // Force clip to be true if the active Transition requires it
18 private static object CoerceClipToBounds(object element, object value)
19 {
20 TransitionPresenter transitionElement = (TransitionPresenter)element;
21 bool clip = (bool)value;
22 if (!clip && transitionElement.IsTransitioning)
23 {
24 Transition transition = transitionElement.Transition;
25 if (transition.ClipToBounds)
26 return true;
27 }
28 return value;
29 }
30
31 public object Content
32 {
33 get { return (object)GetValue(ContentProperty); }
34 set { SetValue(ContentProperty, value); }
35 }
36
37 public static readonly DependencyProperty ContentProperty =
38 DependencyProperty.Register("Content",
39 typeof(object),
40 typeof(TransitionPresenter),
41 new UIPropertyMetadata(null, OnContentChanged, CoerceContent));
42
43 // Don't update content until done transitioning
44 private static object CoerceContent(object element, object value)
45 {
46 TransitionPresenter te = (TransitionPresenter)element;
47 if (te.IsTransitioning)
48 return te.CurrentContentPresenter.Content;
49 return value;
50 }
51
52 private static void OnContentChanged(object element, DependencyPropertyChangedEventArgs e)
53 {
54 TransitionPresenter te = (TransitionPresenter)element;
55 te.BeginTransition();
56 }
57
58 public DataTemplate ContentTemplate
59 {
60 get { return (DataTemplate)GetValue(ContentTemplateProperty); }
61 set { SetValue(ContentTemplateProperty, value); }
62 }
63
64 public static readonly DependencyProperty ContentTemplateProperty =
65 DependencyProperty.Register("ContentTemplate",
66 typeof(DataTemplate),
67 typeof(TransitionPresenter),
68 new UIPropertyMetadata(null, OnContentTemplateChanged));
69
70 private static void OnContentTemplateChanged(object element, DependencyPropertyChangedEventArgs e)
71 {
72 TransitionPresenter te = (TransitionPresenter)element;
73 te.CurrentContentPresenter.ContentTemplate = (DataTemplate)e.NewValue;
74 }
75
76 public DataTemplateSelector ContentTemplateSelector
77 {
78 get { return (DataTemplateSelector)GetValue(ContentTemplateSelectorProperty); }
79 set { SetValue(ContentTemplateSelectorProperty, value); }
80 }
81
82 public static readonly DependencyProperty ContentTemplateSelectorProperty =
83 DependencyProperty.Register("ContentTemplateSelector",
84 typeof(DataTemplateSelector),
85 typeof(TransitionPresenter),
86 new UIPropertyMetadata(null, OnContentTemplateSelectorChanged));
87
88 private static void OnContentTemplateSelectorChanged(object element, DependencyPropertyChangedEventArgs e)
89 {
90 TransitionPresenter te = (TransitionPresenter)element;
91 te.CurrentContentPresenter.ContentTemplateSelector = (DataTemplateSelector)e.NewValue;
92 }
93
94 public bool IsTransitioning
95 {
96 get { return (bool)GetValue(IsTransitioningProperty); }
97 private set { SetValue(IsTransitioningPropertyKey, value); }
98 }
99
100 private static readonly DependencyPropertyKey IsTransitioningPropertyKey =
101 DependencyProperty.RegisterReadOnly("IsTransitioning",
102 typeof(bool),
103 typeof(TransitionPresenter),
104 new UIPropertyMetadata(false));
105
106 public static readonly DependencyProperty IsTransitioningProperty =
107 IsTransitioningPropertyKey.DependencyProperty;
108
109 public Transition Transition
110 {
111 get { return (Transition)GetValue(TransitionProperty); }
112 set { SetValue(TransitionProperty, value); }
113 }
114
115 public static readonly DependencyProperty TransitionProperty =
116 DependencyProperty.Register("Transition", typeof(Transition), typeof(TransitionPresenter), new UIPropertyMetadata(null, null, CoerceTransition));
117
118 private static object CoerceTransition(object element, object value)
119 {
120 TransitionPresenter te = (TransitionPresenter)element;
121 if (te.IsTransitioning) return te._activeTransition;
122 return value;
123 }
124
125 public TransitionSelector TransitionSelector
126 {
127 get { return (TransitionSelector)GetValue(TransitionSelectorProperty); }
128 set { SetValue(TransitionSelectorProperty, value); }
129 }
130
131 public static readonly DependencyProperty TransitionSelectorProperty =
132 DependencyProperty.Register("TransitionSelector", typeof(TransitionSelector), typeof(TransitionPresenter), new UIPropertyMetadata(null));
133
134 public TransitionPresenter()
135 {
136 _children = new UIElementCollection(this, null);
137 ContentPresenter currentContent = new ContentPresenter();
138 _currentHost = new AdornerDecorator();
139 _currentHost.Child = currentContent;
140 _children.Add(_currentHost);
141
142 ContentPresenter previousContent = new ContentPresenter();
143 _previousHost = new AdornerDecorator();
144 _previousHost.Child = previousContent;
145 }
146
147 private void BeginTransition()
148 {
149 TransitionSelector selector = TransitionSelector;
150
151 Transition transition = selector != null ?
152 selector.SelectTransition(CurrentContentPresenter.Content, Content) :
153 Transition;
154
155 if (transition != null)
156 {
157 // Swap content presenters
158 AdornerDecorator temp = _previousHost;
159 _previousHost = _currentHost;
160 _currentHost = temp;
161 }
162
163 ContentPresenter currentContent = CurrentContentPresenter;
164 // Set the current content
165 currentContent.Content = Content;
166 currentContent.ContentTemplate = ContentTemplate;
167 currentContent.ContentTemplateSelector = ContentTemplateSelector;
168
169 if (transition != null)
170 {
171 ContentPresenter previousContent = PreviousContentPresenter;
172
173 if (transition.IsNewContentTopmost)
174 Children.Add(_currentHost);
175 else
176 Children.Insert(0, _currentHost);
177
178 IsTransitioning = true;
179 _activeTransition = transition;
180 CoerceValue(TransitionProperty);
181 CoerceValue(ClipToBoundsProperty);
182 transition.BeginTransition(this, previousContent, currentContent);
183 }
184 }
185
186 // Clean up after the transition is complete
187 internal void OnTransitionCompleted()
188 {
189 _children.Clear();
190 _children.Add(_currentHost);
191 _currentHost.Visibility = Visibility.Visible;
192 _previousHost.Visibility = Visibility.Visible;
193 ((ContentPresenter)_previousHost.Child).Content = null;
194
195 IsTransitioning = false;
196 _activeTransition = null;
197 CoerceValue(TransitionProperty);
198 CoerceValue(ClipToBoundsProperty);
199 CoerceValue(ContentProperty);
200 }
201
202 protected override Size MeasureOverride(Size availableSize)
203 {
204 _currentHost.Measure(availableSize);
205 return _currentHost.DesiredSize;
206 }
207
208 protected override Size ArrangeOverride(Size finalSize)
209 {
210 foreach (UIElement uie in _children)
211 uie.Arrange(new Rect(finalSize));
212 return finalSize;
213 }
214
215 protected override int VisualChildrenCount
216 {
217 get { return _children.Count; }
218 }
219
220 protected override Visual GetVisualChild(int index)
221 {
222 if (index < 0 || index >= _children.Count)
223 throw new ArgumentOutOfRangeException("index");
224 return _children[index];
225 }
226
227 internal UIElementCollection Children
228 {
229 get { return _children; }
230 }
231
232 private ContentPresenter PreviousContentPresenter
233 {
234 get { return ((ContentPresenter)_previousHost.Child); }
235 }
236
237 private ContentPresenter CurrentContentPresenter
238 {
239 get { return ((ContentPresenter)_currentHost.Child); }
240 }
241
242 private UIElementCollection _children;
243
244 private AdornerDecorator _currentHost;
245 private AdornerDecorator _previousHost;
246
247 private Transition _activeTransition;
248 }
249 }