Paradox Game Engine  v1.0.0 beta06
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros Pages
AsyncContentControl.cs
Go to the documentation of this file.
1 // Copyright (c) 2014 Silicon Studio Corp. (http://siliconstudio.co.jp)
2 // This file is distributed under GPL v3. See LICENSE.md for details.
3 using System;
4 using System.Collections.Generic;
5 using System.Linq;
6 using System.Text;
7 using System.Windows.Controls;
8 using System.Windows;
9 using System.Windows.Input;
10 using SiliconStudio.Quantum;
12 using System.Windows.Data;
13 
14 namespace SiliconStudio.Presentation.Controls
15 {
17  {
18  static AsyncContentControl()
19  {
20  DefaultStyleKeyProperty.OverrideMetadata(typeof(AsyncContentControl), new FrameworkPropertyMetadata(typeof(AsyncContentControl)));
21  }
22 
24  {
25  this.Loaded += OnLoaded;
26  }
27 
28  protected override void OnInitialized(EventArgs e)
29  {
30  base.OnInitialized(e);
31 
32  UpdateContentStateProperties(LoadState);
33 
34  StoreRealContent();
35  UpdateContentProperties();
36  }
37 
38  private void OnLoaded(object sender, RoutedEventArgs e)
39  {
40  if (LoadState == ViewModelContentState.NotLoaded && LoadContentOnInitialized)
41  RequestContentLoading();
42  }
43 
44  // === LoadContentOnInitialized =========================================================================================
45 
46  public bool LoadContentOnInitialized
47  {
48  get { return (bool)GetValue(LoadContentOnInitializedProperty); }
49  set { SetValue(LoadContentOnInitializedProperty, value); }
50  }
51 
52  public static readonly DependencyProperty LoadContentOnInitializedProperty = DependencyProperty.Register(
53  "LoadContentOnInitialized",
54  typeof(bool),
55  typeof(AsyncContentControl),
56  new PropertyMetadata(false));
57 
58  // === IsContentNotLoaded =========================================================================================
59 
60  public bool IsContentNotLoaded
61  {
62  get { return (bool)GetValue(IsContentNotLoadedProperty); }
63  private set { SetValue(IsContentNotLoadedPropertyKey, value); }
64  }
65 
66  private static readonly DependencyPropertyKey IsContentNotLoadedPropertyKey = DependencyProperty.RegisterReadOnly(
67  "IsContentNotLoaded",
68  typeof(bool),
69  typeof(AsyncContentControl),
70  new PropertyMetadata());
71  public static readonly DependencyProperty IsContentNotLoadedProperty = IsContentNotLoadedPropertyKey.DependencyProperty;
72 
73  // === IsContentLoading =========================================================================================
74 
75  public bool IsContentLoading
76  {
77  get { return (bool)GetValue(IsContentLoadingProperty); }
78  private set { SetValue(IsContentLoadingPropertyKey, value); }
79  }
80 
81  private static readonly DependencyPropertyKey IsContentLoadingPropertyKey = DependencyProperty.RegisterReadOnly(
82  "IsContentLoading",
83  typeof(bool),
84  typeof(AsyncContentControl),
85  new PropertyMetadata());
86  public static readonly DependencyProperty IsContentLoadingProperty = IsContentLoadingPropertyKey.DependencyProperty;
87 
88  // === IsContentLoaded =========================================================================================
89 
90  public bool IsContentLoaded
91  {
92  get { return (bool)GetValue(IsContentLoadedProperty); }
93  private set { SetValue(IsContentLoadedPropertyKey, value); }
94  }
95 
96  private static readonly DependencyPropertyKey IsContentLoadedPropertyKey = DependencyProperty.RegisterReadOnly(
97  "IsContentLoaded",
98  typeof(bool),
99  typeof(AsyncContentControl),
100  new PropertyMetadata());
101  public static readonly DependencyProperty IsContentLoadedProperty = IsContentLoadedPropertyKey.DependencyProperty;
102 
103  // === AwaitingContent =========================================================================================
104 
105  public object AwaitingContent
106  {
107  get { return GetValue(AwaitingContentProperty); }
108  set { SetValue(AwaitingContentProperty, value); }
109  }
110 
111  public static readonly DependencyProperty AwaitingContentProperty = DependencyProperty.Register(
112  "AwaitingContent",
113  typeof(object),
114  typeof(AsyncContentControl));
115 
116  // === AwaitingContentTemplate =========================================================================================
117 
118  public DataTemplate AwaitingContentTemplate
119  {
120  get { return (DataTemplate)GetValue(AwaitingContentTemplateProperty); }
121  set { SetValue(AwaitingContentTemplateProperty, value); }
122  }
123 
124  public static readonly DependencyProperty AwaitingContentTemplateProperty = DependencyProperty.Register(
125  "AwaitingContentTemplate",
126  typeof(DataTemplate),
127  typeof(AsyncContentControl));
128 
129  // === AwaitingContentTemplateSelector =========================================================================================
130 
131  public DataTemplateSelector AwaitingContentTemplateSelector
132  {
133  get { return (DataTemplateSelector)GetValue(AwaitingContentTemplateSelectorProperty); }
134  set { SetValue(AwaitingContentTemplateSelectorProperty, value); }
135  }
136 
137  public static readonly DependencyProperty AwaitingContentTemplateSelectorProperty = DependencyProperty.Register(
138  "AwaitingContentTemplateSelector",
139  typeof(DataTemplateSelector),
140  typeof(AsyncContentControl));
141 
142  // === LoadState =========================================================================================
143 
144  public ViewModelContentState LoadState
145  {
146  get { return (ViewModelContentState)GetValue(LoadStateProperty); }
147  set { SetValue(LoadStateProperty, value); }
148  }
149 
150  public static readonly DependencyProperty LoadStateProperty = DependencyProperty.Register(
151  "LoadState",
152  typeof(ViewModelContentState),
153  typeof(AsyncContentControl),
154  new FrameworkPropertyMetadata(ViewModelContentState.NotLoaded, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnLoadStatePropertyChanged),
155  OnValidateLoadStateValue);
156 
157  public static void OnLoadStatePropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
158  {
159  var acc = (AsyncContentControl)sender;
160  var oldState = (ViewModelContentState)e.OldValue;
161  var newState = (ViewModelContentState)e.NewValue;
162 
163  acc.UpdateContentStateProperties(newState);
164  acc.UpdateContentProperties();
165 
166  acc.OnLoadStateChanged(oldState, newState);
167  }
168 
169  private void UpdateContentStateProperties(ViewModelContentState newState)
170  {
171  IsContentNotLoaded = newState == ViewModelContentState.NotLoaded;
172  IsContentLoading = newState == ViewModelContentState.Loading;
173  IsContentLoaded = newState == ViewModelContentState.Loaded;
174  }
175 
176  protected virtual void OnLoadStateChanged(ViewModelContentState oldValue, ViewModelContentState newValue)
177  {
178  RaiseEvent(new RoutedPropertyChangedEventArgs<ViewModelContentState>(oldValue, newValue, LoadStateChangedEvent));
179  }
180 
181  public static bool OnValidateLoadStateValue(object value)
182  {
183  return Enum.IsDefined(typeof(ViewModelContentState), value);
184  }
185 
186  public static readonly RoutedEvent LoadStateChangedEvent = EventManager.RegisterRoutedEvent(
187  "LoadStateChanged",
188  RoutingStrategy.Bubble,
189  typeof(DependencyPropertyChangedEventHandler),
190  typeof(AsyncContentControl));
191 
192  public event DependencyPropertyChangedEventHandler LoadStateChanged
193  {
194  add { AddHandler(LoadStateChangedEvent, value); }
195  remove { RemoveHandler(LoadStateChangedEvent, value); }
196  }
197 
198  // === RequestContentLoading =========================================================================================
199 
200  public void RequestContentLoading()
201  {
202  OnRequestContentLoading();
203  }
204 
205  protected virtual void OnRequestContentLoading()
206  {
207  var command = LoadContentCommand;
208  if (command != null && command.CanExecute(null)) // TODO: try/catch CanExecute
209  command.Execute(null); // TODO: try/catch Execute
210  }
211 
212  // === LoadContentCommand =========================================================================================
213 
214  public ICommand LoadContentCommand
215  {
216  get { return (ICommand)GetValue(LoadContentCommandProperty); }
217  set { SetValue(LoadContentCommandProperty, value); }
218  }
219 
220  public static readonly DependencyProperty LoadContentCommandProperty = DependencyProperty.Register(
221  "LoadContentCommand",
222  typeof(ICommand),
223  typeof(AsyncContentControl));
224 
225  // === CancelContentLoadingCommand =========================================================================================
226 
227  public ICommand CancelContentLoadingCommand
228  {
229  get { return (ICommand)GetValue(CancelContentLoadingCommandProperty); }
230  set { SetValue(CancelContentLoadingCommandProperty, value); }
231  }
232 
233  public static readonly DependencyProperty CancelContentLoadingCommandProperty = DependencyProperty.Register(
234  "CancelContentLoadingCommand",
235  typeof(ICommand),
236  typeof(AsyncContentControl));
237 
238  // =====================================================================================
239 
240  private object storedContent;
241  private object storedContentTemplate;
242  private object storedContentTemplateSelector;
243 
244  public void StoreRealContent()
245  {
246  storedContent = GetPropertyValue(ContentProperty);
247  storedContentTemplate = GetPropertyValue(ContentTemplateProperty);
248  storedContentTemplateSelector = GetPropertyValue(ContentTemplateSelectorProperty);
249  }
250 
251  private void UpdateContentProperties()
252  {
253  if (LoadState != ViewModelContentState.Loaded)
254  {
255  SetValue(ContentProperty, AwaitingContent);
256  SetValue(ContentTemplateProperty, AwaitingContentTemplate);
257  SetValue(ContentTemplateSelectorProperty, AwaitingContentTemplateSelector);
258  }
259  else
260  {
261  SetPropertyValue(ContentProperty, storedContent);
262  SetPropertyValue(ContentTemplateProperty, storedContentTemplate);
263  SetPropertyValue(ContentTemplateSelectorProperty, storedContentTemplateSelector);
264  }
265  }
266 
267  private object GetPropertyValue(DependencyProperty property)
268  {
269  object result = null;
270 
271  if (BindingOperations.IsDataBound(this, property))
272  {
273  result = BindingOperations.GetBindingBase(this, property);
274  if (result == null)
275  result = BindingOperations.GetBindingExpressionBase(this, property);
276  }
277  else
278  result = GetValue(property);
279 
280  return result;
281  }
282 
283  private void SetPropertyValue(DependencyProperty property, object value)
284  {
285  if (value is BindingBase)
286  SetBinding(property, (BindingBase)value);
287  else if (value is BindingExpressionBase)
288  SetBinding(property, ((BindingExpressionBase)value).ParentBindingBase);
289  else
290  SetValue(property, value);
291  }
292  }
293 }
virtual void OnLoadStateChanged(ViewModelContentState oldValue, ViewModelContentState newValue)
static void OnLoadStatePropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)