BusyIndiââcatorã«é¢ããæè¿ã®æçš¿ã«å¿ããŠããã®åé¡ã«é¢ãã圌ã®çµéš/ããžã§ã³ãå
±æããããšã«ããŸããã ç§ã®æèŠã§ã¯ããã®èšäºã¯éçšç®¡çã®ææšã®ããåçŽãªå®è£
ã瀺ããŠããŸãã ä»ã§ã¯èª°ããç±ç·ããéçºäŒç€Ÿã®æ¢è£œåã䜿çšã§ããŸããããã®å Žåã®ãæŒããããæœè±¡åãã®åé¡ã¯éåžžã«ç·æ¥ã«ãªããŸãã æ¢æã®ææšãäžèªç¶ãªæ¹æ³ã§äœ¿çšãããšãå¿
ç¶çã«æ²æšãªçµæã«ã€ãªãããŸãã ãããã£ãŠããã©ã®ããã«æ©èœãããããæ³åããããšã¯éåžžã«éèŠã§ãã
Otma3ka
w Kodilãã BusyIndiââcator ãã«é¢ããè¿é£ã®æçš¿ã«è§ŠçºãããŠ- æ¿ããç±æã§ãããã¹ããã©ã¯ãã£ã¹ã¬ã€ãããæ¯ãè¿ãããšãªãã³ãŒããæžããŸããã
- å®éãã¬ãã¹ã³ãã©ãã ãããåŠã³ãå
éšã®ã 10k Clock ããæŽæ°ãããã¯è峿·±ã
- äžèšãšå£æ»
çãªæéäžè¶³ã®ãããã³ãŒãã¯åªé
ã«èŒããŸãã
- ãŸããã³ãŒãã¯æ®éçã§ã¯ãããŸããã æ¢åã®ã¢ããªã±ãŒã·ã§ã³ã¢ãŒããã¯ãã£ã«çµ±åããã®ãé£ããå ŽåããããŸã
- ããããããã¯ã·ã³ãã«ã§ããããããïŒå°ãªããšãç§ã«ã¯ïŒããããŠæãéèŠãªããšã¯[åå°]åå°ããªãããšã§ã[/åå°]
åé¡ã®å£°æ
ã¯ããããã...äžããããïŒ
- äœããã®åœ¢åŒã®ããŒã¿å
¥åãé
眮ãããã¡ã€ã³ãŠã£ã³ããŠ

- ãŠã£ã³ããŠå
ã®ãã©ãŒã ã¯ã ãããªãã¯ããããã£BusyAdorner BusyAdornerãæã€BaseAdornableControlïŒUserControl ïŒãŸãã¯åå«ïŒã¯ã©ã¹ã®ã€ã³ã¹ã¿ã³ã¹ã§ãã
- ãã®ããããã£ã®ã»ãã¿ãŒã§ã¯ãããžãŒã€ã³ãžã±ãŒã¿ãæ¥ç¶/åæãããŸã
- ã¡ã€ã³ãŠã£ã³ããŠã®DataContextã«ã¯ããã¢ViewModelã®ã€ã³ã¹ã¿ã³ã¹ã®å€ãå²ãåœãŠãããŸãïŒããã®å€æ°
Piãææã®äººã§åŒã³åºãã SimpleBusyAdornerDemoViewModel ïŒ - ViewModelã«ã¯1ã€ã®ããã³ããããã£IsBusyãããããã®ããããã£ã®å€æŽã€ãã³ãã®ä»£ããã«ã¢ã¯ã·ã§ã³[bool]ããããŸã
- ç°¡åã«ããããã«ã€ãã³ãã«ç
©ããããŸããã§ããïŒè¿œå ã®ãã³ãã©ãŒã¯ã©ã¹ãšãã®åŒæ°ã宣èšããããããŸããã§ããïŒ
- ããžãã¯ã¯æ¬¡ã®ãšããã§ããIsBusyå€ã倿Žãããšã ã¢ã¯ã·ã§ã³[bool] IsBusyChangedãåŒæ°ãšããŠæ°ããIsBusyå€ã§äœåããŸã
- Action [bool]ãžã®ãµãã¹ã¯ã©ã€ãIsBusyChangedã¯ã BaseAdornableControlã€ã³ã¹ã¿ã³ã¹ã®BusyAdornerããããã£ã®å€ãnull ïŒã¢ãããŒãåæïŒãŸãã¯ãŒã以å€ã®å€ïŒã¢ãããŒãæ¥ç¶ïŒã«èšå®ããŸãã
- ç¹°ãè¿ããŸãããç°¡åã«ããããã«ã IsBusyå€ãViewModelã«å転ãããã¿ã³ããŠã£ã³ããŠã«é
眮ããŸããããããšãã°ãWebãµãŒãã¹ã«èŠæ±ãéä¿¡ããŠå¿çãåä¿¡ãããšããViewModelããããè¡ãå¿
èŠãããããšãç¥ã£ãŠããŸã
ã¡ã€ã³ãŠã£ã³ããŠ
<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 {
ããã§ã¯ãã¹ãŠãç°¡åã§ãã ãŠã£ã³ããŠã«ã¯ãããŒã¯ãããã©ãŒã ããããŸãã ãã®äžã«ã¯ãViewModelã®
IsBusyããããã£ã®å€ã倿Žãããã¿ã³ããããŸãã ãã§ã«æžããããã«ããã®ãã¿ã³ã¯ã¿ã¹ã¯ã®éå§ãšçµäºãæš¡å£ããŸãïŒéåæïŒã ãã®å Žåãéåæã¿ã¹ã¯ãšViewModelã®çžäºäœçšã®ããžãã¯ãã©ã®ããã«å®è£
ããããã¯éèŠã§ã¯ãããŸããã
TPLã©ã€ãã©ãªã䜿çšãããŠãããšä»®å®ããŸãïŒãšããã§ãããã¯ç§ã®mcDonnaldsã§ã-ãç§ã¯Lovinã ãã...ãïŒã ã¡ã€ã³ãŠã£ã³ããŠã®ãã¶ã€ããŒã§ã
IsBusy倿Žãµãã¹ã¯ãªãã·ã§ã³ãã¢ã¯ã·ã§ã³ã«äœæãããŸããã ãã®å Žåããã³ãã©ãŒã¯1ã€ã ããªã®ã§ãActionã䜿çšã§ããŸãã ãã以å€ã®å Žåã¯ãããªã²ãŒããçç¥ã§ããŸããã§ããã ãã®ããããã³ãã©ãŒã¯
AdornableControlã®BusyAdornerå€ãèšå®ããŸãïŒã€ã³ãžã±ãŒã¿ãŒãåæããå Žåã¯nullãã¢ã¿ããããå Žåã¯nullã§ã¯ãããŸããã
Busyadorner
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);
ããã¯äžçš®ã®ãã²ãããã§ãããéçšViewModelã瀺ã
äžæ°å³ãªèšå¿µç¢ã
çæããããšãçè§£ãããŸãã ãã®å Žåãç»åã¯éçã«ãªããŸãããå転ãã€ããã¯ã¹ã
RotateTransformã®è§åºŠãæŽæ°ããããã®ååãªã¿ã€ããŒããããŸããã ããã§ã¯ãã¢ãã¡ãŒã·ã§ã³ã®æ³ååãéæŸã§ããŸãã ã¡ãªã¿ã«ãTPLã®åãã¿ã¹ã¯ã䜿çšããŠãç»åã®å転è§åºŠãã¹ã ãŒãºã«å€æŽã§ããŸãïŒHMM ...
ã²ãŒã ã«ãŒããšããŠã®ã¿ã¹ã¯
ïŒè©ŠããŠã¿ãŠãã ããïŒ ïŒã
ãããã£ãŠã次ã®ããã«ãªããŸãã

ç¥ã¯äœãç¥ã£ãŠããã®ã§ã¯ãããŸããããæŠå¿µã®ãã¢ã³ã¹ãã¬ãŒã·ã§ã³ãšããŠéããŠããŸãã
BaseAdornableControl
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 {
éèŠãªãç¥ãã ã è£
食ã«ã©ãããããã³ã³ãããŒã«ãã¢ã³ããŒãããåã«ãè£
食ã眪ïŒã¡ã¢ãªãªãŒã¯ïŒããåãé¢ãå¿
èŠããããŸãã AdornerLayerã®ããžãã¯ã¯éåžžã«è€éã§ãããèŠæå¿ã倱ããšãã¬ãŒãããããããšãã§ããŸãã ã ããç§ã¯ããªãã«èŠåããŸãã...
SimpleBusyAdornerDemoViewModel
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] } }
eventã®ä»£ããã«Actionãæã€ãWTF-codeããé€ããŠãMVVMãã¿ãŒã³ã«ç²ŸéããŠãã人ã«ãšã£ãŠç¹å¥ãªããšã¯ãããŸããã
è¿œå æ©èœ-BusyAdornerManager
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 } }
ããã¯ãä»»æã®ã³ã³ãããŒã«ã«è£
食ãã¶ãäžããããããã«èšèšããããµãŒãã¹ã§ãã ãŸããkakulka-ããã¯ã·ã³ã°ã«ãã³ã§ã¯ãªããåãªãéçãªã¯ã©ã¹ã«ããããšãã§ããã¢ãã¬ããŒã®ãªã¹ãã¯ãŸã 䟡å€ããããŸããã
ãããã«
gitããã®ä»ã®ãã€ã³ããèŠåœãããªãå Žæã«åºããŠãççŽã«èšã£ãŠããã®ãããªäºçްãªããšãå°ç¡ãã«ããããªãã ç§ã«ãšã£ãŠããã®æçš¿ã¯ã¹ããããã§ãããæè/ç¥èãæŽçãã詊ã¿ã§ãããhabreviewããŒããžã®ãã±ããã§ãã ãããããããã
誰ãã䟿å©
ã ãšæãã§ãããã ããã§ç§ãã¡ã¯å¥åº·ãæ¹å€ããŸãããã³ãŒãã¹ã¿ã€ã«ã®ã¬ã€ããã«ã€ããŠã¯ããªããŒãªãã§...
UPD
ç¶æ¿ã®ãªãŒããŒãããã®åé¡
ã«ã€ã㊠...ãã©ãŒã ã®ãã¥ãŒã¯äžè¬ã«UserControlã§ãã UserControlã®ä»£ããã«UserControlExãŸãã¯åãBaseAdornableControlãªã©ã®XAMLã§èšè¿°ããããšã¯æ¬åœã«å¯èœã§ããïŒå€§ããªãªãŒããŒãããã§ããïŒ
çŽç²ã«MVVMã¢ãããŒãã䜿çšãããšãã質å
ã« ... DependencyPropertyãBaseAdornableControlã«è¿œå ããIsBusy ViewModelã«ãã€ã³ãããã®ã¯ç°¡åã§ãã ãã®ããããã£ã倿Žãããã³ãã©ã§ãå€éšããæ³šæããã®ãšåãããšãè¡ããŸãã ããã¯ããµãŒãããŒãã£è£œåã®å
éšç¹æ§ãåæ ããæŸèæãæ§ç¯ãããããã¯ããã«ä¿¡é Œæ§ããããŸãã ãµãŒãããŒãã£ã®éçºè
ãèªåèªèº«ã®å
éšãå€ããããšãã©ãæãã誰ãç¥ã£ãŠããŸããïŒ
ã¢ãããŒãViewModelããããã£ã«çŽæ¥ãã€ã³ãããåé¡
ã«ã€ã㊠...è§£èª¬ã§æžããããã«ãDependencyPropertyãå«ããå¿
èŠããããŸãããã®ããã«ã¯ãããšãã°ãã¢ãããŒãFrameworkElementããç¶æ¿ããå¿
èŠããããŸãã ãããŠãããã¯éåžžã«æ·±å»ãªãªãŒããŒãããã«ãªããŸããç¹ã«ãè£
食è
ãåžžã«ã¡ã¢ãªã«ãã³ã°ã¢ããããå Žåã§ãã
Visifireã³ãŒãã
ãæ¥œãã¿ãã ãã ã ãŸãã¯ãå°ãªããšãSNOOP'omã¯BarChart'aããªãŒãæ©ããŸãã ããã§ããã£ãŒãã®åããŒã«å¯ŸããŠã1ã€ãŸãã¯2ã€ã®äžéãã£ã³ãã¹ãäœæãããŸãã ããã«ãDataPointã¯FrameworkElementãç¶æ¿ããDataPointãäœãã«ãã€ã³ããããã
Colorããããã£ãèšå®ããŸãïŒããã¯Colorã§ã¯ãªããBrushã§ã¯ãããŸããïŒã ãããŠåè«ã¯ããããã®DataPointsã¯FrameworkElementsã§ããããã£ãŒãã®ãã£ã³ãã¹ã«é
眮ããããšããããšã§ãã ãããã«ãFrameworkElementsã®ãã1ã€ã®ã³ã¬ã¯ã·ã§ã³ãæ°ããäœæãããæç»ãããŸãã ãã®çµæãVisifireãã£ãŒãã¯ãã§ã«600以äžã®èŠçŽ ã§ãã¬ãŒããããå§ããŠããŸãã æ¯èŒã®ããã«ïŒåçããŒã¿è¡šç€º->æãç·ã°ã©ã-> 60kèŠçŽ ïŒç¹ã«æ»ãããªã°ã©ãã£ãã¯ã¹ïŒ->éåžžæç»ãããŸãã
ãããã£ãŠãViewModelã«çŽæ¥ãã€ã³ããŒã決å®ãããšããŸã£ããäžèŠãªãªãŒããŒããããçºçããŸãã
UPD2
ToolKitã€ã³ãã£ã±ãŒã¿ãŒã®äœ¿çšã«é¢ãã質å
ã« ...
ã³ã¡ã³ãããããŸã...èªãã§ãã ããã ããšãã°ã次ã®ã³ãŒãïŒ
BackgroundWorker worker = new BackgroundWorker(); worker.DoWork += (o, ea) => {
ããã§è¡šç€ºãããã€ã³ãžã±ãŒã¿ã¯ãåºæ¬çã«ãéåæã¿ã¹ã¯ã®é²è¡ç¶æ³ããŠãŒã¶ãŒã«éç¥ããããã«èšèšãããç¹å¥ãªãã€ã¢ãã°ã§ãã ãã®ãã€ã¢ãã°ã¯ããŠã£ã³ããŠ/ã¢ããªã±ãŒã·ã§ã³å
šäœã§å®è¡ãããŸãã ããã«è¡šç€ºãããã€ã³ãžã±ãŒã¿ã¯ãã¡ã¢ãªæ¶è²»éãé«ããªãããšãæããã«ãã³ã³ãããŒã«ããšã«åå¥ã«ãã³ã°ã¢ããã§ããŸãã ç°ãªãã«ããŽãªãŒã