WisdomSoft - for your serial experiences.

6.4 範囲コントロール

スライダーやスクロールバーのような、ある一定の範囲内にある特定の値を指すコントロールを紹介します。このような範囲コントロールは、すべて System.Windows.Controls.Primitives.RangeBase クラスから派生しています。

6.4.1 スライダー

スライダーや進捗バー、スクロールバーのような、ある一定の数値範囲を表現するコントロールは、範囲コントロールという概念で System.Windows.Controls.Primitives.RangeBase クラスに抽象化されています。スライダーなど、一定の範囲の中からユーザーが選択するようなコントロールは、このクラスから派生しています。

スライダーを表示するには System.Windows.Controls.Slider クラスを利用します。このクラスは RangeBase を継承しています。スライダーは、ある一定範囲の値を選択するつまみを保有するバーを表示するコントロールです。音量のような、スライド式の設定項目に利用します。

System.Windows.Controls.Slider クラス
System.Object 
   System.Windows.Threading.DispatcherObject 
     System.Windows.DependencyObject 
       System.Windows.Media.Visual 
         System.Windows.UIElement 
           System.Windows.FrameworkElement 
             System.Windows.Controls.Control 
               System.Windows.Controls.Primitives.RangeBase 
                System.Windows.Controls.Slider
[LocalizabilityAttribute(LocalizationCategory.Ignore)] 
[TemplatePartAttribute(Name="PART_SelectionRange", Type=typeof(FrameworkElement))] 
[TemplatePartAttribute(Name="PART_Track", Type=typeof(Track))] 
public class Slider : RangeBase

Slider クラスのコンストラクタはパラメータを受け取りません。

Slider クラスのコンストラクタ
public Slider ()

既定のスライダーは水平方向のバーを持ちます、スライダーのバーを垂直方向に表示させたい場合は Orientation プロパティを用います。

Slider クラス Orientation プロパティ
public Orientation Orientation { get; set; }

Orientation プロパティは、バーの方向を表します。このプロパティは、方向を表す Orientation 列挙体のいずれかのメンバを設定してください。既定では Horizontal が設定されているので、垂直方向にしたい場合は Vertical を設定します。

コード1
using System;
using System.Windows;
using System.Windows.Controls;

class Test {
	[STAThread]
	public static void Main() {
		Slider slider1 = new Slider();

		Slider slider2 = new Slider();
		slider2.Height = 100;
		slider2.Orientation = Orientation.Vertical;

		StackPanel panel = new StackPanel();
		panel.Children.Add(slider1);
		panel.Children.Add(slider2);

		Window wnd = new Window();
		wnd.Content = panel;

		Application app = new Application();
		app.Run(wnd);
	}
}
実行結果
コード1 実行結果

コード1は、生成した 2 つのスライダーを表示するプログラムです。slider1 変数に保存したスライダは、プロパティを変更せずに規定の状態で表示しています。既定の状態では、スライダーは水平方向であることが確認できます。slider2 オブジェクトは、Orientation プロパティから方向を変更しているため、垂直方向のスライダーとして表示されます。

6.4.2 範囲と値

RangeBase から派生するクラスには、基本となる 3 つの値を管理する役割があります。スライダーやスクロールバーなどには、共通して一定の範囲の値を選択する性質があるため、範囲を決定するための最小値、最大値と、現在選択中の値が最も重要なプロパティとなります。これらのプロパティは全て RangeBase クラスで宣言されています。

スライダーのバーで選択できる範囲は最小値と最大値で決定されます。最小値は Minimum プロパティ、最大値は Maximum プロパティから設定・取得します。

RangeBase クラス Minimum プロパティ
[BindableAttribute(true)] 
public double Minimum { get; set; }
RangeBase クラス Maximum プロパティ
[BindableAttribute(true)] 
public double Maximum { get; set; }

Minimum プロパティの既定の値は 0 、Maximum プロパティの既定の値は 1 となっています。

スライダには、コントロール上にマウスでドラッグ可能なつまみを表示します。このつまみの場所が Minimum と Maximum の範囲で選択した値となります。選択中の値は Value プロパティから取得することができます。

RangeBase クラス Value プロパティ
[BindableAttribute(true)] 
public double Value { get; set; }

Value プロパティの既定の値は 0 に設定されています。Value に設定する値は、常に Minimum から Muximun までの範囲にある値しか設定されません。

つまみを動かすなどして、Value プロパティが変更されると ValueChanged イベントが発生します。

RangeBase クラス ValueChanged イベント
public event RoutedPropertyChangedEventHandler<double> ValueChanged

このイベントには System.Windows.RoutedPropertyChangedEventHandler デリゲートを登録することができます。

System.Windows.RoutedPropertyChangedEventHandler デリゲート
public delegate void RoutedPropertyChangedEventHandler<T> (
    Object sender,
    RoutedPropertyChangedEventArgs<T> e
)

RoutedPropertyChangedEventHandler デリゲートは、プロパティが変更されたときに発生するイベント用のハンドラを提供します。e パラメータは、System.Windows.RoutedPropertyChangedEventArgs クラスのオブジェクトを受け取ります。

System.Windows.RoutedPropertyChangedEventArgs クラス
System.Object 
   System.EventArgs 
     System.Windows.RoutedEventArgs 
      System.Windows.RoutedPropertyChangedEventArgs
public class RoutedPropertyChangedEventArgs<T> : RoutedEventArgs

RoutedPropertyChangedEventArgs クラスは、変更されたプロパティの情報を提供します。このクラスは変更されたプロパティの値を提供するためにジェネリックが用いられています。型パラメータ T には、プロパティの型に応じて適切な型が指定されます。RangeBase クラスの Value は double 型なので、ValueChanged イベントの場合は double となります。

渡された RoutedPropertyChangedEventArgs オブジェクトには、プロパティが変更される前の古い値と、プロパティに設定される新しい値が格納されています。変更される前の値は OldValue プロパティから、新しい値は NewValue プロパティから取得できます。

RoutedPropertyChangedEventArgs クラス OldValue プロパティ
public T OldValue { get; }
RoutedPropertyChangedEventArgs クラス NewValue プロパティ
public T NewValue { get; }

値がどのように変化したのかを知りたい場合は、これらのプロパティを比較すると良いでしょう。

コード2
using System;
using System.Windows;
using System.Windows.Controls;

class Test : Window {
	[STAThread]
	public static void Main() {
		Window wnd = new Test();
		Application app = new Application();
		app.Run(wnd);
	}

	private Label label;
	private Slider slider;

	public Test() {
		slider = new Slider();
		slider.Minimum = 1;
		slider.Maximum = 100;
		slider.Value = 50;
		slider.ValueChanged += sliderValueChanged;

		label = new Label();
		label.Content = "Value=" + slider.Value;

		StackPanel panel = new StackPanel();
		panel.Children.Add(label);
		panel.Children.Add(slider);

		Content = panel;
	}

	private void sliderValueChanged(
		Object sender, RoutedPropertyChangedEventArgs<double> e)
	{
		label.Content = "Value=" + slider.Value;
	}
}
実行結果
コード2 実行結果

コード2は、スライダーのつまみを動かすと、上部のラベルにスライダーの現在の値がリアルタイムで表示されるというプログラムです。ValueChanged イベントで Value プロパティの変更を監視し、Value プロパティが変更されると、ラベルにスライダーの現在の Value プロパティの値を表示させています。

6.4.3 目盛り

スライダーには、任意の間隔で目盛りを表示させることができます。目盛りの表示には Ticks プロパティを用います。

Slider クラス Ticks プロパティ
[BindableAttribute(true)] 
public DoubleCollection Ticks { get; set; }

Ticks プロパティは、目盛りの位置を表す double 型の値の配列を管理する DoubleCollection 型のコレクションを保有しています。このオブジェクトに、目盛りとして表示する値を設定します。

既定では、目盛りは表示しないように設定されています。目盛りをどのように表示するかは TickPlacement プロパティから設定します。

Slider クラス TickPlacement プロパティ
[BindableAttribute(true)] 
public TickPlacement TickPlacement { get; set; }

このプロパティには、目盛りをどのように表示するかを表す System.Windows.Controls.Primitives.TickPlacement 列挙体のいずれかのメンバを設定します。既定の値は、目盛りを表示しないことを表す None メンバが設定されています。

System.Windows.Controls.Primitives.TickPlacement 列挙体
public enum TickPlacement

この列挙体には、表1のようなメンバが記述されています。

表1 TickPlacement 列挙体のメンバ
メンバ 意味
Both 両脇に目盛りを表示する
None 目盛りは表示されない
BottomRight 水平方向のバーの場合は下、垂直方向のバーの場合は右
TopLeft 水平方向のバーの場合は上、垂直方向のバーの場合は左
 

例えば、Both メンバを設定すればバーの両側に目盛りが表示されます。None 以外の値を設定し、適切に Ticks プロパティに表示する目盛りの値を設定してください。

コード3
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;

class Test {
	[STAThread]
	public static void Main() {
		Slider slider = new Slider();
		slider.Maximum = 10;
		slider.TickPlacement = TickPlacement.Both;
		for(double t = 0 ; t < 10 ; t += 0.5) {
			slider.Ticks.Add(t);
		}

		Window wnd = new Window();
		wnd.Content = slider;

		Application app = new Application();
		app.Run(wnd);
	}
}
実行結果
コード3 実行結果

コード3では、0 から 10 までの値を設定することができるスライダーを表示しています。このスライダーには Ticks プロパティに、0.5 の間隔で目盛りとして表示する値を設定します。

6.4.4 進捗バー

アプリケーションが時間の掛かる処理を実行するとき、ユーザーにどの程度まで処理が進んでいるかを知らせる進捗バーが利用されます。こうしたコントロールを用意しない場合、ユーザーは長い時間アプリケーションが反応を返さないためビジー状態になってしまったと判断してしまうかもしれません。

進捗バーを表示するには System.Windows.Controls.ProgressBar クラスを使います。このクラスもまた、スライダーと同様に RangeBase を継承しています。

System.Windows.Controls.ProgressBar クラス
System.Object 
   System.Windows.Threading.DispatcherObject 
     System.Windows.DependencyObject 
       System.Windows.Media.Visual 
         System.Windows.UIElement 
           System.Windows.FrameworkElement 
             System.Windows.Controls.Control 
               System.Windows.Controls.Primitives.RangeBase 
                System.Windows.Controls.ProgressBar
[TemplatePartAttribute(Name="PART_Indicator", Type=typeof(FrameworkElement))] 
[TemplatePartAttribute(Name="PART_Track", Type=typeof(FrameworkElement))] 
public class ProgressBar : RangeBase

このクラスのコンストラクタは、パラメータを受け取りません。

ProgressBar クラスのコンストラクタ
public ProgressBar()

進捗バーは、スライダーのようにユーザーが Value プロパティを自由に変更することはできません。最小値、最大値、現在の値などは全て RangeBase クラスのものなので、使い方はスライダーと同じです。

コード4
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;

class Test {
	[STAThread]
	public static void Main() {
		ProgressBar bar = new ProgressBar();
		bar.Margin = new Thickness(10);
		bar.Maximum = 10;
		bar.Value = 7;

		StackPanel panel = new StackPanel();
		panel.Children.Add(bar);

		Window wnd = new Window();
		wnd.Content = panel;

		Application app = new Application();
		app.Run(wnd);
	}
}
実行結果
コード4 実行結果

コード4は、最小値が 0、最大値が 10、現在の値が 7 の状態の進捗バーを表示しています。このように、進捗バーを用いることで、時間の掛かる処理を行っている間、どの程度まで処理が進んでいるかをユーザーに知らせることができます。

6.4.5 スクロールバー

 スクロールバーも、RangeBase クラスを継承する範囲コントロールの一種です。基本的にはスライダーなどと同様に扱うことができますが、通常のシナリオではスクロールバーを単体のコントロールとして使用することはほとんどありません。スクロールバーを表示するには System.Windows.Controls.Primitives.ScrollBar クラスを用います。

System.Windows.Controls.Primitives.ScrollBar クラス
System.Object 
   System.Windows.Threading.DispatcherObject 
     System.Windows.DependencyObject 
       System.Windows.Media.Visual 
         System.Windows.UIElement 
           System.Windows.FrameworkElement 
             System.Windows.Controls.Control 
               System.Windows.Controls.Primitives.RangeBase 
                System.Windows.Controls.Primitives.ScrollBar
[LocalizabilityAttribute(LocalizationCategory.NeverLocalize)] 
[TemplatePartAttribute(Name="PART_Track", Type=typeof(Track))] 
public class ScrollBar : RangeBase

このクラスのコンストラクタは、パラメータを受け取りません。

ScrollBar クラスのコンストラクタ
public ScrollBar ()

スクロールバーのつまみも、スライダーと同様にユーザーが任意に動かして Value プロパティの値を変更することができます。ただし、スクロールバーはつまみの幅を ViewportSize プロパティから設定することができます。

ScrollBar クラス ViewportSize プロパティ
public double ViewportSize { get; set; }

このプロパティの既定の値は 0 です。よって、スクロールバーの既定のつまみは最小の幅で表示されます。このプロパティには 0 から Maximum プロパティの値までを設定することができます。もし ViewportSize プロパティの値と Maximum プロパティの値が同一であれば、つまみの幅がバーと同じサイズとなってしまうため、つまみを動かすことはできなくなってしまいます。

コード5
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;

class Test {
	[STAThread]
	public static void Main() {
		ScrollBar bar1 = new ScrollBar();
		bar1.Orientation = Orientation.Horizontal;
		bar1.Maximum = 10;

		ScrollBar bar2 = new ScrollBar();
		bar2.Orientation = Orientation.Horizontal;
		bar2.Maximum = 10;
		bar2.ViewportSize = 1;

		ScrollBar bar3 = new ScrollBar();
		bar3.Orientation = Orientation.Horizontal;
		bar3.Maximum = 10;
		bar3.ViewportSize = 5;

		StackPanel panel = new StackPanel();
		panel.Children.Add(bar1);
		panel.Children.Add(bar2);
		panel.Children.Add(bar3);

		Window wnd = new Window();
		wnd.Content = panel;

		Application app = new Application();
		app.Run(wnd);
	}
}
実行結果
コード5 実行結果

コード5は、つまみの幅が異なる 3 つのスクロールバーを表示しています。スクロールバーの場合も、最小値 Minimum、最大値 Maximum、現在の値 Value プロパティなどの使い方は、スライダーと同じです。