3using System.ComponentModel;
6using System.Threading.Tasks;
98 #region Bindable Properties
101 public static readonly BindableProperty TaskProperty =
108 set => this.SetValue(TaskProperty, value);
112 public static readonly BindableProperty PendingTemplateProperty =
113 BindableProperty.Create(nameof(PendingTemplate), typeof(DataTemplate), typeof(
TaskView<TProgress>),
default(DataTemplate));
114 public DataTemplate PendingTemplate
116 get => (DataTemplate)this.GetValue(PendingTemplateProperty);
117 set => this.SetValue(PendingTemplateProperty, value);
120 public static readonly BindableProperty RunningTemplateProperty =
121 BindableProperty.Create(nameof(RunningTemplate), typeof(DataTemplate), typeof(
TaskView<TProgress>),
default(DataTemplate));
122 public DataTemplate RunningTemplate
124 get => (DataTemplate)this.GetValue(RunningTemplateProperty);
125 set => this.SetValue(RunningTemplateProperty, value);
128 public static readonly BindableProperty RefreshingTemplateProperty =
129 BindableProperty.Create(nameof(RefreshingTemplate), typeof(DataTemplate), typeof(
TaskView<TProgress>),
default(DataTemplate));
130 public DataTemplate RefreshingTemplate
132 get => (DataTemplate)this.GetValue(RefreshingTemplateProperty);
133 set => this.SetValue(RefreshingTemplateProperty, value);
136 public static readonly BindableProperty SucceededTemplateProperty =
137 BindableProperty.Create(nameof(SucceededTemplate), typeof(DataTemplate), typeof(
TaskView<TProgress>),
default(DataTemplate));
138 public DataTemplate SucceededTemplate
140 get => (DataTemplate)this.GetValue(SucceededTemplateProperty);
141 set => this.SetValue(SucceededTemplateProperty, value);
144 public static readonly BindableProperty ErrorTemplateProperty =
145 BindableProperty.Create(nameof(ErrorTemplate), typeof(DataTemplate), typeof(
TaskView<TProgress>),
default(DataTemplate));
146 public DataTemplate ErrorTemplate
148 get => (DataTemplate)this.GetValue(ErrorTemplateProperty);
149 set => this.SetValue(ErrorTemplateProperty, value);
152 public static readonly BindableProperty DefaultTemplateProperty =
153 BindableProperty.Create(nameof(DefaultTemplate), typeof(DataTemplate), typeof(
TaskView<TProgress>),
default(DataTemplate));
154 public DataTemplate DefaultTemplate
156 get => (DataTemplate)this.GetValue(DefaultTemplateProperty);
157 set => this.SetValue(DefaultTemplateProperty, value);
161 public static readonly BindableProperty PendingViewProperty =
162 BindableProperty.Create(nameof(PendingView), typeof(View), typeof(
TaskView<TProgress>),
default(View));
163 public View PendingView
165 get => (View)this.GetValue(PendingViewProperty);
166 set => this.SetValue(PendingViewProperty, value);
169 public static readonly BindableProperty RunningViewProperty =
170 BindableProperty.Create(nameof(RunningView), typeof(View), typeof(
TaskView<TProgress>),
default(View));
171 public View RunningView
173 get => (View)this.GetValue(RunningViewProperty);
174 set => this.SetValue(RunningViewProperty, value);
177 public static readonly BindableProperty RefreshingViewProperty =
178 BindableProperty.Create(nameof(RefreshingView), typeof(View), typeof(
TaskView<TProgress>),
default(View));
179 public View RefreshingView
181 get => (View)this.GetValue(RefreshingViewProperty);
182 set => this.SetValue(RefreshingViewProperty, value);
185 public static readonly BindableProperty SucceededViewProperty =
186 BindableProperty.Create(nameof(SucceededView), typeof(View), typeof(
TaskView<TProgress>),
default(View));
187 public View SucceededView
189 get => (View)this.GetValue(SucceededViewProperty);
190 set => this.SetValue(SucceededViewProperty, value);
193 public static readonly BindableProperty ErrorViewProperty =
194 BindableProperty.Create(nameof(ErrorView), typeof(View), typeof(
TaskView<TProgress>),
default(View));
195 public View ErrorView
197 get => (View)this.GetValue(ErrorViewProperty);
198 set => this.SetValue(ErrorViewProperty, value);
201 public static readonly BindableProperty DefaultViewProperty =
202 BindableProperty.Create(nameof(DefaultView), typeof(View), typeof(
TaskView<TProgress>),
default(View));
203 public View DefaultView
205 get => (View)this.GetValue(DefaultViewProperty);
206 set => this.SetValue(DefaultViewProperty, value);
210 public static readonly BindableProperty PendingControlTemplateProperty =
211 BindableProperty.Create(nameof(PendingControlTemplate), typeof(ControlTemplate), typeof(
TaskView<TProgress>),
default(ControlTemplate));
212 public ControlTemplate PendingControlTemplate
214 get => (ControlTemplate)this.GetValue(PendingControlTemplateProperty);
215 set => this.SetValue(PendingControlTemplateProperty, value);
218 public static readonly BindableProperty RunningControlTemplateProperty =
219 BindableProperty.Create(nameof(RunningControlTemplate), typeof(ControlTemplate), typeof(
TaskView<TProgress>),
default(ControlTemplate));
220 public ControlTemplate RunningControlTemplate
222 get => (ControlTemplate)this.GetValue(RunningControlTemplateProperty);
223 set => this.SetValue(RunningControlTemplateProperty, value);
226 public static readonly BindableProperty RefreshingControlTemplateProperty =
227 BindableProperty.Create(nameof(RefreshingControlTemplate), typeof(ControlTemplate), typeof(
TaskView<TProgress>),
default(ControlTemplate));
228 public ControlTemplate RefreshingControlTemplate
230 get => (ControlTemplate)this.GetValue(RefreshingControlTemplateProperty);
231 set => this.SetValue(RefreshingControlTemplateProperty, value);
234 public static readonly BindableProperty SucceededControlTemplateProperty =
235 BindableProperty.Create(nameof(SucceededControlTemplate), typeof(ControlTemplate), typeof(
TaskView<TProgress>),
default(ControlTemplate));
236 public ControlTemplate SucceededControlTemplate
238 get => (ControlTemplate)this.GetValue(SucceededControlTemplateProperty);
239 set => this.SetValue(SucceededControlTemplateProperty, value);
242 public static readonly BindableProperty ErrorControlTemplateProperty =
243 BindableProperty.Create(nameof(ErrorControlTemplate), typeof(ControlTemplate), typeof(
TaskView<TProgress>),
default(ControlTemplate));
244 public ControlTemplate ErrorControlTemplate
246 get => (ControlTemplate)this.GetValue(ErrorControlTemplateProperty);
247 set => this.SetValue(ErrorControlTemplateProperty, value);
250 public static readonly BindableProperty DefaultControlTemplateProperty =
251 BindableProperty.Create(nameof(DefaultControlTemplate), typeof(ControlTemplate), typeof(
TaskView<TProgress>),
default(ControlTemplate));
252 public ControlTemplate DefaultControlTemplate
254 get => (ControlTemplate)this.GetValue(DefaultControlTemplateProperty);
255 set => this.SetValue(DefaultControlTemplateProperty, value);
260 #region Task Change Handling
262 private static void OnTaskChanged(BindableObject bindable,
object oldValue,
object newValue)
267 OldTask.PropertyChanged -= Control.Task_PropertyChanged;
271 NewTask.PropertyChanged += Control.Task_PropertyChanged;
273 Control.UpdateContent();
276 private void Task_PropertyChanged(
object? sender, PropertyChangedEventArgs e)
281 MainThread.BeginInvokeOnMainThread(this.UpdateContent);
287 #region Content Selection & Creation
295 private View? GetContent(View inlineView, DataTemplate?
template, ControlTemplate? controlTemplate)
297 if (inlineView is not
null)
300 if (
template is not
null)
302 object Content =
template.CreateContent();
303 if (Content is View View)
305 if (Content is ViewCell Cell)
309 if (controlTemplate is not
null)
311 ContentView View =
new ContentView { ControlTemplate = controlTemplate };
321 private View? GetDefaultContent() => this.GetContent(this.DefaultView, this.DefaultTemplate, this.DefaultControlTemplate);
326 private View? SelectContent()
328 if (this.Task is
null)
329 return this.GetDefaultContent();
332 if (this.Task.IsPending)
334 View? Content = this.GetContent(this.PendingView, this.PendingTemplate, this.PendingControlTemplate);
335 if (Content is not
null)
338 Content = this.GetContent(this.RunningView, this.RunningTemplate, this.RunningControlTemplate);
339 if (Content is not
null)
344 if (this.Task.IsRunning)
346 if (this.Task.IsRefreshing)
348 View? Content = this.GetContent(this.RefreshingView, this.RefreshingTemplate, this.RefreshingControlTemplate);
349 if (Content is not
null)
353 View? RunningContent = this.GetContent(this.RunningView, this.RunningTemplate, this.RunningControlTemplate);
354 if (RunningContent is not
null)
355 return RunningContent;
359 if (this.Task.IsSucceeded)
361 View? Content = this.GetContent(this.SucceededView, this.SucceededTemplate, this.SucceededControlTemplate);
362 if (Content is not
null)
367 if (this.Task.IsFailed ||
this.Task.IsCanceled)
369 View? Content = this.GetContent(this.ErrorView, this.ErrorTemplate, this.ErrorControlTemplate);
370 if (Content is not
null)
374 return this.GetDefaultContent();
379 #region Animation & Content Update
384 private async
void UpdateContent()
386 View? NewContent = this.SelectContent();
387 if (NewContent is
null)
390 NewContent.BindingContext = this.BindingContext;
394 if (this.Content is not
null)
396 View OldContent = this.Content;
397 await OldContent.FadeToAsync(0, 250);
398 this.Content = NewContent;
399 NewContent.Opacity = 0;
400 await NewContent.FadeToAsync(1, 250);
404 this.Content = NewContent;
405 NewContent.Opacity = 0;
406 await NewContent.FadeToAsync(1, 250);
411 this.Content.Opacity = 1;
415 protected override void OnBindingContextChanged()
417 base.OnBindingContextChanged();
419 if (this.Content is not
null)
420 this.Content.BindingContext = this.BindingContext;
A ContentView control that displays the state of an asynchronous operation defined by an ObservableTa...
Provides a data-binding friendly mechanism to manage and report the status of asynchronous operations...
ObservableTaskStatus State
Gets the current state.