Extended Controls - BusyIndicator

 ビジー状態を表すインジケータを表示するためのコントロールです。

ページ内リンク

基本的な使い方

 BusyIndicator コントロールは、UI が処理中であることを示すためのインジケータを表示するためのコントロールです。 バックグラウンドで処理をおこないながら UI を更新するため、主に非同期処理をおこなっている場合に使用します。 ここでは async/await による簡単な非同期処理を使用します。

 まず、重たい処理を表現するために、次のような SampleModel クラスを定義します。 本当におこないたい処理は DoHeavyWorkCore() メソッドですが、これを実行するタスクを返すメソッドが DoHeavyWorkAsync() メソッドです。 そして、DoHeavyWorkAsync() メソッドのほうを公開することで、外側からは同じタスクで重たい処理をさせないようにしています。

namespace Section4_3.Models
{
    using System.Threading;
    using System.Threading.Tasks;

    public class SampleModel
    {
        /// <summary>
        /// 重たい処理を別タスクでおこないます。
        /// </summary>
        /// <returns></returns>
        public Task DoHeavyWorkAsync()
        {
            return Task.Run(() =>
            {
                DoHeavyWorkCore();
            });
        }

        /// <summary>
        /// 重たい処理をおこないます。
        /// </summary>
        private void DoHeavyWorkCore()
        {
            // 仮想的な重たい処理として 10[s] 間待機する
            Thread.Sleep(10000);
        }
    }
}
Code 1 : SampleModel クラスのコード

 次に BusyIndicator コントロールを使った簡単なサンプルコードを示します。 Button コントロールと TextBlock コントロールを縦に並べた StackPanel コントロールの上に被さるように BusyIndicator コントロールを配置しています。 BusyIndicator コントロールは、IsBusy プロパティが true にならない限り表示されないため、普段は StackPanel コントロールの内容のみが表示される形となります。

 なお、BusyIndicator には Message プロパティがあります。 下記のサンプルコードでは TextBlock コントロールを別に用意していますが、 BusyIndicator コントロールのインジケータ下部にメッセージを表示させることもできます。 こちらの場合、メッセージ表示用に UI のスペースを確保する必要がなくなります。

<YK:Window x:Class="Section4_3.Views.MainView"
           xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
           xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
           xmlns:YK="clr-namespace:YKToolkit.Controls;assembly=YKToolkit.Controls"
           Title="MainView" Height="500" Width="500"
           WindowStartupLocation="CenterScreen">
    <Grid>
        <StackPanel VerticalAlignment="Center">
            <Button Content="Click me." Command="{Binding ButtonCommand}" Margin="20" />
            <TextBlock Margin="20">
                <Run Text="Message :" />
                <Run Text="{Binding Message, Mode=OneWay}" />
            </TextBlock>
        </StackPanel>

        <YK:BusyIndicator IsBusy="{Binding IsBusy}" />
    </Grid>
</YK:Window>
Code 2 : BusyIndicator コントロールのサンプルコード

 上記の MainView と SampleModel をつなぐための MainViewModel クラスのコードを次に示します。 MainView のボタンを押すと重たい処理が開始されるようにするため、ButtonCommand プロパティから非同期処理が開始されるようにしています。 非同期処理をおこなうには、処理をおこなうタスクの前に await 演算子を置きます。 また、await 演算子を使用することを許可するために、そのメソッドの修飾子に async を追加します。

namespace Section4_3.ViewModels
{
    using Section4_3.Model;
    using YKToolkit.Bindings;

    public class MainViewModel : NotificationObject
    {
        /// <summary>
        /// サンプルモデルのインスタンス
        /// </summary>
        private SampleModel model = new SampleModel();

        #region 公開プロパティ
        private bool isBusy;
        /// <summary>
        /// ビジー状態かどうかを取得します。
        /// </summary>
        public bool IsBusy
        {
            get { return isBusy; }
            private set { SetProperty(ref isBusy, value); }
        }
        private string message;
        /// <summary>
        /// メッセージを取得または設定します。
        /// </summary>
        public string Message
        {
            get { return message; }
            set { SetProperty(ref message, value); }
        }

        private DelegateCommand buttonCommand;
        /// <summary>
        /// ボタンのコマンドを取得します。
        /// </summary>
        public DelegateCommand ButtonCommand
        {
            get
            {
                if (buttonCommand == null)
                    buttonCommand = new DelegateCommand(_ =>
                    {
                        DoCommand();
                    });
                return buttonCommand;
            }
        }
        #endregion 公開プロパティ

        /// <summary>
        /// 処理をおこないます。
        /// </summary>
        private async void DoCommand()
        {
            Message = "処理を開始します。";
            IsBusy = true;

            // 重たい処理を非同期でおこなう
            await model.DoHeavyWorkAsync();

            IsBusy = false;
            Message = "処理を終了しました。";
        }
    }
}
Code 3 : BusyIndicator コントロールのための ViewModel のサンプルコード

 上記のサンプルコードの実装結果は下図のようになります。

Fig.1 : BusyIndicator コントロールのサンプル画面
Fig.2 : ボタンを押すと非同期処理が開始される

Designed by CSS.Design Sample