<Window x:Class="MyBusyAdorner.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:views="clr-namespace:MyBusyAdorner.Views" xmlns:adorners="clr-namespace:MyBusyAdorner.Adorners" Title="MainWindow" Height="350" Width="525"> <Grid> <Grid.RowDefinitions> <RowDefinition /> <RowDefinition Height="Auto"/> </Grid.RowDefinitions> <views:BaseAdornableControl x:Name="AdornableControl" BusyAdorner="{x:Null}" Margin="15"/> <Button Content="Attach/Detach" Grid.Row="1" Click="Button_Click"/> </Grid> </Window>
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; using MyBusyAdorner.ViewModels; using MyBusyAdorner.Adorners; namespace MyBusyAdorner { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { private SimpleBusyAdornerDemoViewModel _viewModel; public MainWindow() { InitializeComponent(); DataContext = _viewModel = new SimpleBusyAdornerDemoViewModel(); _viewModel.IsBusyChanged = new Action<bool>((newValue) => { AttachDetachBusyAdorner(newValue); }); } private void AttachDetachBusyAdorner(bool isBusy) { AdornableControl.BusyAdorner = isBusy ? new BusyAdorner(AdornableControl) : null; } private void Button_Click(object sender, RoutedEventArgs e) { _viewModel.IsBusy = !_viewModel.IsBusy; } } }
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows.Documents; using System.Windows; using System.Windows.Media; namespace MyBusyAdorner.Adorners { public class BusyAdorner : Adorner { public BusyAdorner(UIElement adornedElement) : base(adornedElement) { } protected override void OnRender(DrawingContext drawingContext) { var adornedControl = this.AdornedElement as FrameworkElement; if (adornedControl == null) return; Rect rect = new Rect(0,0, adornedControl.ActualWidth, adornedControl.ActualHeight); // Some arbitrary drawing implements. SolidColorBrush renderBrush = new SolidColorBrush(Colors.Green); renderBrush.Opacity = 0.2; Pen renderPen = new Pen(new SolidColorBrush(Colors.Navy), 1.5); double renderRadius = 5.0; double dist = 15; double cntrX = rect.Width / 2; double cntrY = rect.Height / 2; double left = cntrX - dist; double right = cntrX + dist; double top = cntrY - dist; double bottom = cntrY + dist; // Draw four circles near to center. drawingContext.PushTransform(new RotateTransform(45, cntrX, cntrY)); drawingContext.DrawEllipse(renderBrush, renderPen, new Point { X = left, Y = top}, renderRadius, renderRadius); drawingContext.DrawEllipse(renderBrush, renderPen, new Point { X = right, Y = top }, renderRadius, renderRadius); drawingContext.DrawEllipse(renderBrush, renderPen, new Point { X = right, Y = bottom }, renderRadius, renderRadius); drawingContext.DrawEllipse(renderBrush, renderPen, new Point { X = left, Y = bottom }, renderRadius, renderRadius); } } }
<!-- ... .. -->
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; using MyBusyAdorner.Adorners; namespace MyBusyAdorner.Views { /// <summary> /// Interaction logic for BaseAdornableControl.xaml /// </summary> public partial class BaseAdornableControl : UserControl { #region [Fields] //private List<Adorner> _adorners = new List<Adorner>(); private BusyAdorner _busyAdorner; #endregion [/Fields] #region [Properties] public BusyAdorner BusyAdorner { get { return _busyAdorner; } set { DetachBusyAdorner(); _busyAdorner = value; if (value != null) { AttachBusyAdorner(); } } } private void AttachBusyAdorner() { if (_busyAdorner == null) return; var adornerLayer = AdornerLayer.GetAdornerLayer(this); adornerLayer.Add(_busyAdorner); } private void DetachBusyAdorner() { var adornerLayer = AdornerLayer.GetAdornerLayer(this); if (adornerLayer != null && _busyAdorner != null) { adornerLayer.Remove(_busyAdorner); } } #endregion [/Properties] public BaseAdornableControl() { InitializeComponent(); this.Unloaded += new RoutedEventHandler(BaseAdornableControl_Unloaded); } void BaseAdornableControl_Unloaded(object sender, RoutedEventArgs e) { DetachBusyAdorner(); } } }
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ComponentModel; namespace MyBusyAdorner.ViewModels { public class SimpleBusyAdornerDemoViewModel : INotifyPropertyChanged { #region [Fields] private bool _isBusy; #endregion [/Fields] #region [Properties] public bool IsBusy { get { return _isBusy; } set { if (value != _isBusy) { _isBusy = value; RaisePropertyChanged("IsBusy"); RaiseIsBusyChanged(); } } } public Action<bool> IsBusyChanged { get; set; } #endregion [/Properties] #region [Private Methods] private void RaiseIsBusyChanged() { if (IsBusyChanged != null) { IsBusyChanged(_isBusy); } } #endregion [/Private Methods] #region [INotifyPropertyChanged] public event PropertyChangedEventHandler PropertyChanged; private void RaisePropertyChanged(string propertyName) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } } #endregion [/INotifyPropertyChanged] } }
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Collections.ObjectModel; using MyBusyAdorner.Adorners; using System.Windows; using System.Windows.Documents; namespace MyBusyAdorner.Services { public sealed class BusyAdornerManager { #region [Fieds] private List<BusyAdorner> _adorners; #endregion [/Fieds] #region [Public Methods] public void AddBusyAdorner(UIElement adornedElement) { if (adornedElement == null) return; var adorner = new BusyAdorner(adornedElement); _adorners.Add(adorner); } public void RemoveAllAdorners(UIElement adornedElement) { if (adornedElement == null) return; var adornerLayer = AdornerLayer.GetAdornerLayer(adornedElement); foreach (var adorner in adornerLayer.GetAdorners(adornerLayer)) { adornerLayer.Remove(adorner); } } #endregion [/Public Methods] #region Singleton private static volatile BusyAdornerManager instance; private static object syncRoot = new Object(); private BusyAdornerManager() { } public static BusyAdornerManager Instance { get { if (instance == null) { lock (syncRoot) { if (instance == null) instance = new BusyAdornerManager(); } } return instance; } } #endregion } }
BackgroundWorker worker = new BackgroundWorker(); worker.DoWork += (o, ea) => { //long-running-process code System.Threading.Thread.Sleep(10000); DispatchService.Dispatch((Action)(() => { //update the UI code goes here // ... })); }; worker.RunWorkerCompleted += (o, ea) => { this.ResetIsBusy(); //here the BusyIndicator.IsBusy is set to FALSE }; this.SetIsBusy(); //here the BusyIndicator.IsBusy is set to TRUE worker.RunWorkerAsync();
Source: https://habr.com/ru/post/142243/
All Articles