6.4 範囲コントロール
6.4.1 スライダー
スライダーや進捗バー、スクロールバーのような、ある一定の数値範囲を表現するコントロールは、範囲コントロールという概念で System.Windows.Controls.Primitives.RangeBase クラスに抽象化されています。スライダーなど、一定の範囲の中からユーザーが選択するようなコントロールは、このクラスから派生しています。
スライダーを表示するには System.Windows.Controls.Slider クラスを利用します。このクラスは RangeBase を継承しています。スライダーは、ある一定範囲の値を選択するつまみを保有するバーを表示するコントロールです。音量のような、スライド式の設定項目に利用します。
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 クラスのコンストラクタはパラメータを受け取りません。
public Slider ()
既定のスライダーは水平方向のバーを持ちます、スライダーのバーを垂直方向に表示させたい場合は Orientation プロパティを用います。
public Orientation Orientation { get; set; }
Orientation プロパティは、バーの方向を表します。このプロパティは、方向を表す Orientation 列挙体のいずれかのメンバを設定してください。既定では Horizontal が設定されているので、垂直方向にしたい場合は Vertical を設定します。
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は、生成した 2 つのスライダーを表示するプログラムです。slider1 変数に保存したスライダは、プロパティを変更せずに規定の状態で表示しています。既定の状態では、スライダーは水平方向であることが確認できます。slider2 オブジェクトは、Orientation プロパティから方向を変更しているため、垂直方向のスライダーとして表示されます。
6.4.2 範囲と値
RangeBase から派生するクラスには、基本となる 3 つの値を管理する役割があります。スライダーやスクロールバーなどには、共通して一定の範囲の値を選択する性質があるため、範囲を決定するための最小値、最大値と、現在選択中の値が最も重要なプロパティとなります。これらのプロパティは全て RangeBase クラスで宣言されています。
スライダーのバーで選択できる範囲は最小値と最大値で決定されます。最小値は Minimum プロパティ、最大値は Maximum プロパティから設定・取得します。
[BindableAttribute(true)] public double Minimum { get; set; }
[BindableAttribute(true)] public double Maximum { get; set; }
Minimum プロパティの既定の値は 0 、Maximum プロパティの既定の値は 1 となっています。
スライダには、コントロール上にマウスでドラッグ可能なつまみを表示します。このつまみの場所が Minimum と Maximum の範囲で選択した値となります。選択中の値は Value プロパティから取得することができます。
[BindableAttribute(true)] public double Value { get; set; }
Value プロパティの既定の値は 0 に設定されています。Value に設定する値は、常に Minimum から Muximun までの範囲にある値しか設定されません。
つまみを動かすなどして、Value プロパティが変更されると ValueChanged イベントが発生します。
public event RoutedPropertyChangedEventHandler<double> ValueChanged
このイベントには System.Windows.RoutedPropertyChangedEventHandler デリゲートを登録することができます。
public delegate void RoutedPropertyChangedEventHandler<T> ( Object sender, RoutedPropertyChangedEventArgs<T> e )
RoutedPropertyChangedEventHandler デリゲートは、プロパティが変更されたときに発生するイベント用のハンドラを提供します。e パラメータは、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 プロパティから取得できます。
public T OldValue { get; }
public T NewValue { get; }
値がどのように変化したのかを知りたい場合は、これらのプロパティを比較すると良いでしょう。
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は、スライダーのつまみを動かすと、上部のラベルにスライダーの現在の値がリアルタイムで表示されるというプログラムです。ValueChanged イベントで Value プロパティの変更を監視し、Value プロパティが変更されると、ラベルにスライダーの現在の Value プロパティの値を表示させています。
6.4.3 目盛り
スライダーには、任意の間隔で目盛りを表示させることができます。目盛りの表示には Ticks プロパティを用います。
[BindableAttribute(true)] public DoubleCollection Ticks { get; set; }
Ticks プロパティは、目盛りの位置を表す double 型の値の配列を管理する DoubleCollection 型のコレクションを保有しています。このオブジェクトに、目盛りとして表示する値を設定します。
既定では、目盛りは表示しないように設定されています。目盛りをどのように表示するかは TickPlacement プロパティから設定します。
[BindableAttribute(true)] public TickPlacement TickPlacement { get; set; }
このプロパティには、目盛りをどのように表示するかを表す System.Windows.Controls.Primitives.TickPlacement 列挙体のいずれかのメンバを設定します。既定の値は、目盛りを表示しないことを表す None メンバが設定されています。
public enum TickPlacement
この列挙体には、表1のようなメンバが記述されています。
メンバ | 意味 |
---|---|
Both | 両脇に目盛りを表示する |
None | 目盛りは表示されない |
BottomRight | 水平方向のバーの場合は下、垂直方向のバーの場合は右 |
TopLeft | 水平方向のバーの場合は上、垂直方向のバーの場合は左 |
例えば、Both メンバを設定すればバーの両側に目盛りが表示されます。None 以外の値を設定し、適切に Ticks プロパティに表示する目盛りの値を設定してください。
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では、0 から 10 までの値を設定することができるスライダーを表示しています。このスライダーには Ticks プロパティに、0.5 の間隔で目盛りとして表示する値を設定します。
6.4.4 進捗バー
アプリケーションが時間の掛かる処理を実行するとき、ユーザーにどの程度まで処理が進んでいるかを知らせる進捗バーが利用されます。こうしたコントロールを用意しない場合、ユーザーは長い時間アプリケーションが反応を返さないためビジー状態になってしまったと判断してしまうかもしれません。
進捗バーを表示するには System.Windows.Controls.ProgressBar クラスを使います。このクラスもまた、スライダーと同様に RangeBase を継承しています。
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
このクラスのコンストラクタは、パラメータを受け取りません。
public ProgressBar()
進捗バーは、スライダーのようにユーザーが Value プロパティを自由に変更することはできません。最小値、最大値、現在の値などは全て RangeBase クラスのものなので、使い方はスライダーと同じです。
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は、最小値が 0、最大値が 10、現在の値が 7 の状態の進捗バーを表示しています。このように、進捗バーを用いることで、時間の掛かる処理を行っている間、どの程度まで処理が進んでいるかをユーザーに知らせることができます。
6.4.5 スクロールバー
スクロールバーも、RangeBase クラスを継承する範囲コントロールの一種です。基本的にはスライダーなどと同様に扱うことができますが、通常のシナリオではスクロールバーを単体のコントロールとして使用することはほとんどありません。スクロールバーを表示するには 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
このクラスのコンストラクタは、パラメータを受け取りません。
public ScrollBar ()
スクロールバーのつまみも、スライダーと同様にユーザーが任意に動かして Value プロパティの値を変更することができます。ただし、スクロールバーはつまみの幅を ViewportSize プロパティから設定することができます。
public double ViewportSize { get; set; }
このプロパティの既定の値は 0 です。よって、スクロールバーの既定のつまみは最小の幅で表示されます。このプロパティには 0 から Maximum プロパティの値までを設定することができます。もし ViewportSize プロパティの値と Maximum プロパティの値が同一であれば、つまみの幅がバーと同じサイズとなってしまうため、つまみを動かすことはできなくなってしまいます。
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は、つまみの幅が異なる 3 つのスクロールバーを表示しています。スクロールバーの場合も、最小値 Minimum、最大値 Maximum、現在の値 Value プロパティなどの使い方は、スライダーと同じです。