Advertisement
Guest User

AsyncIndicator

a guest
Apr 17th, 2012
407
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Text;
  6. using System.Windows;
  7. using System.Windows.Controls;
  8. using Lion.Utils.Common.Extensions;
  9.  
  10. namespace Lion.Utils.Wpf
  11. {
  12.     /// <summary>
  13.     /// Busy indicator helper for automatically on/off when async operation in process.
  14.     /// Supported any ContentControls with property IsBusy and list controls with property ItemsSource
  15.     /// <para></para>
  16.     /// Usage:
  17.     /// <code>
  18.     ///     &lt;BusyIndicator AsyncIndicator.Attached="True"&gt;
  19.     ///        &lt;DataGrid ItemsSource="{Binding WorkItems, IsAsync=True}"&gt;
  20.     ///            ...
  21.     ///        &lt;/DataGrid&gt;
  22.     ///     &lt;/BusyIndicator&gt;
  23.     /// </code>
  24.     /// </summary>
  25.     public static class AsyncIndicator
  26.     {
  27.         static AsyncIndicator() { }
  28.  
  29.         private const string ListPropertyName = "ItemsSource";
  30.         private const string IsBusyPropertyName = "IsBusy";
  31.  
  32.         private static readonly DependencyProperty _busyIndicatorProperty = DependencyProperty.RegisterAttached("%BusyIndicatorProperty%",
  33.             typeof (ContentControl), typeof (DependencyObject));
  34.  
  35.         public static readonly DependencyProperty AttachedProperty = DependencyProperty.RegisterAttached("Attached",
  36.             typeof (bool), typeof (ContentControl), new FrameworkPropertyMetadata(false, AttachedChanged));
  37.  
  38.         public static Boolean GetAttached(UIElement element)
  39.         {
  40.             return (Boolean) element.GetValue(AttachedProperty);
  41.         }
  42.  
  43.         public static void SetAttached(UIElement element, Boolean value)
  44.         {
  45.             element.SetValue(AttachedProperty, value);
  46.         }
  47.  
  48.         private static void SetPropertyChangedCallback(this DependencyProperty dp, DependencyObject d,
  49.             PropertyChangedCallback callback, bool reset = false)
  50.         {
  51.             if (dp == null || d == null) return;
  52.             var typ = d.GetType();
  53.             var x = dp.GetMetadata(typ);
  54.             var oldValue = x.SetPropValue("Sealed", false, false, true);
  55.             x.PropertyChangedCallback -= callback;
  56.             if (!reset)
  57.                 x.PropertyChangedCallback += callback;
  58.             x.SetPropValue("Sealed", oldValue, false, true);
  59.         }
  60.  
  61.         private static void AttachedChanged(DependencyObject busyIndicator, DependencyPropertyChangedEventArgs e)
  62.         {
  63.             ContentControl.ContentProperty.SetPropertyChangedCallback(busyIndicator, ContentChangedCallback);
  64.         }
  65.  
  66.         private static DependencyProperty GetItemsSourceProperty(this DependencyObject contentObject)
  67.         {
  68.             return contentObject == null
  69.                        ? null
  70.                        : (contentObject.GetFieldValue(ListPropertyName + "Property") ??
  71.                           contentObject.GetPropValue(ListPropertyName + "Property")) as DependencyProperty;
  72.         }
  73.  
  74.         private static object GetItemsSourceValue(this DependencyObject contentObject)
  75.         {
  76.             return contentObject == null ? null : contentObject.GetValue(contentObject.GetItemsSourceProperty());
  77.         }
  78.  
  79.         private static DependencyObject GetBusyIndicator(this DependencyObject contentObject)
  80.         {
  81.             return contentObject == null ? null : contentObject.GetValue(_busyIndicatorProperty) as DependencyObject;
  82.         }
  83.  
  84.         private static void SetBusyIndicator(this DependencyObject contentObject, DependencyObject busyIndicator)
  85.         {
  86.             if (contentObject != null)
  87.             {
  88.                 contentObject.GetItemsSourceProperty().SetPropertyChangedCallback(contentObject, ItemsSourceChangedCallback,
  89.                                                                            busyIndicator == null);
  90.                 contentObject.SetValue(_busyIndicatorProperty, busyIndicator);
  91.             }
  92.             busyIndicator.UpdateBusyIndicator(contentObject);
  93.         }
  94.  
  95.         private static void UpdateBusyIndicator(this DependencyObject busyIndicator, DependencyObject contentObject)
  96.         {
  97.             if (busyIndicator == null) return;
  98.             if (contentObject == null)
  99.                 busyIndicator.SetPropValue(IsBusyPropertyName, false);
  100.             else
  101.                 busyIndicator.SetPropValue(IsBusyPropertyName, contentObject.GetItemsSourceValue() == null);
  102.         }
  103.  
  104.         private static bool IsAttached(this DependencyObject busyIndicator)
  105.         {
  106.             return (bool) busyIndicator.GetValue(AttachedProperty);
  107.         }
  108.  
  109.         private static void ContentChangedCallback(DependencyObject busyIndicator, DependencyPropertyChangedEventArgs e)
  110.         {
  111.             if (!busyIndicator.IsAttached()) return;
  112.             (e.OldValue as DependencyObject).SetBusyIndicator(null);
  113.             (e.NewValue as DependencyObject).SetBusyIndicator(busyIndicator);
  114.         }
  115.  
  116.         private static void ItemsSourceChangedCallback(DependencyObject contentObject, DependencyPropertyChangedEventArgs e)
  117.         {
  118.             contentObject.GetBusyIndicator().UpdateBusyIndicator(contentObject);
  119.         }
  120.     }
  121.  
  122. }
Advertisement
RAW Paste Data Copied
Advertisement