Edited at

Windows GUIプログラミング入門2 デジタル時計


はじめに

今回はデジタル時計を作ります。

ウィンドウサイズに合わせて時刻の文字サイズも変わります。

完成図

wbg2-26.png

キーワード:ウィンドウリサイズ, タスクバー表示, 最前面表示, Viewbox, DispatcherTimer, タイマー, ドキュメントコメント, イベント, using整理

[注意]

これまでの回で説明済みの操作方法等は、説明を省略したり簡略化している場合があります。


開発環境


  • Windows 10

  • Visual Studio Community 2015 Update 3


作ってみる

新規プロジェクトでWPFアプリケーションを選択します。

プロジェクト名はWpfApplication2にします。


ウィンドウの高さを変える

画面デザイナのウィンドウのタイトルバーの部分をクリックしてください。

そうするとXAMLのWindowタグの部分が選択状態になり、プロパティウィンドウの「種類」がWindowになります。

wbg2-01.png

プロパティの検索ボックスに hei と入力してください。

プロパティの一覧がheiを含むものにフィルタリングされて、Heightが出てきます。

wbg2-02.png

Heightプロパティに 250 を入力してEnterを押してください。

Windowの高さが変わります。

wbg2-03.png

プロパティの検索ボックス右端の×ボタンを押してフィルタリングを解除してください。

wbg2-04.png


ウィンドウのその他の設定

引き続きWindowのプロパティを設定していきます。

ResizeModeCanResizeWithGripに設定してリサイズグリップを表示させます。

wbg2-05.png

リサイズグリップが表示されて、ウィンドウをサイズ変更できることが視覚的にわかりやすくなりました。

ついでにShowInTaskbarのチェックを外して、実行時にタスクバーに表示しないようにします。

wbg2-06.png

Titleプロパティに時計を入力します。これはタイトルバーに表示される内容です。

Topmostにチェックを入れます。ウィンドウが前面に表示されるようになります。

wbg2-07.png

変更したプロパティを元に戻したい場合やクリアしたい場合は、

プロパティ右端のをクリックし、メニューから「リセット」を選択します。

wbg2-08.png


Viewboxの追加

次はViewboxというものを追加します。

画面デザイナでタイトルバーの下、白い部分をクリックします。

そうするとGridが選択状態になります。

左のツールボックスの検索ボックスに v と入力します。

Viewboxが見つけやすくなったのでGridにドラッグ&ドロップします。

wbg2-09.png

XAMLのGridタグの中にViewboxが入ったでしょうか?

失敗した場合はCtrl + Zで前の状態に戻ります。

うまくいったらツールボックスの検索ボックス×ボタンを押してフィルタリングを解除しておきます。

間違ってツールボックス自体の×ボタンを押してしまわないように。

その場合はメニューの「表示」 - 「ツールボックス」で再表示できます。

wbg2-10.png


TextBlockの追加

ツールボックスからTextBlockViewboxの上にドラッグ&ドロップします。

wbg2-11.png

XAMLの階層構造は


  • Grid


    • Viewbox


      • TextBlock





となっているでしょうか?


表示を整える

Viewboxの不要なプロパティを削除します。

XAMLで画像の通り、全プロパティを範囲選択してDeleteキーで削除します。

wbg2-12.png

幅や高さ指定などが削除されたのでウィンドウサイズいっぱいに表示されました。

これでウィンドウサイズに合わせて拡大縮小するテキストが実現できました。

wbg2-13.png

TextBlockTextWrappingプロパティは削除し、Textプロパティは00:00:00を設定します。

wbg2-14.png


ロジック部分記述


usingの追加

コードビハインドを開きます。MainWindow.xaml.csのタブをクリックするか、ソリューションエクスプローラーで該当ファイルをダブルクリックします。

usingにSystem.Windows.Threading;を追加します。

これは後で出てくるDispatcherTimerクラスやDispatcherPriority列挙型が属する名前空間(識別名)です。

usingを書いておくとSystem.Windows.Threading.DispatcherTimerと書くところを、DispatcherTimerと省略して書けるようになります。


名前空間の例

using System;

using 日本.静岡県.浜松市;

namespace NameSpaceSample
{
class Program
{
static void Main()
{
日本.東京都.足立区.田中一郎.SayHello();

// usingしているので「日本.静岡県.浜松市」は省略可
日本.静岡県.浜松市.田中一郎.SayHello();

// usingしている「日本.静岡県.浜松市」の田中一郎が使用される
田中一郎.SayHello();
}
}
}

namespace 日本.東京都.足立区
{
static class 田中一郎
{
public static void SayHello()
{
Console.WriteLine("田中一郎です。");
}
}
}

namespace 日本.静岡県.浜松市
{
static class 田中一郎
{
public static void SayHello()
{
Console.WriteLine("こんにちは。");
}
}
}


wbg2-15.png


タイマーのフィールド(変数)追加

class定義の中に、以下のタイマー変数を入力します。

private DispatcherTimer timer;

そして変数定義の上で/(スラッシュ)を3つ入力します。

wbg2-16.png

そうすると図のようなコメントが作成されます。

summaryタグの間、カーソル位置のあるところから時刻表示用タイマーとコメント内容を入力してください。

wbg2-17.png


タイマー生成メソッド(関数)の追加

コンストラクタ定義(public MainWindow())の下あたりに以下のコードを入力してください。

private DispatcherTimer CreateTimer()

{
}

wbg2-18.png

CreateTimerメソッド(関数)の上でも///でコメントを書いてください。

そして中にタイマーを生成して返す処理を書きます。

public partial class MainWindow : Window

{
/// <summary>
/// 時刻表示用タイマー
/// </summary>
private DispatcherTimer timer;

public MainWindow()
{
InitializeComponent();
}

/// <summary>
/// タイマー生成処理
/// </summary>
/// <returns>生成したタイマー</returns>
private DispatcherTimer CreateTimer()
{
// タイマー生成(優先度はアイドル時に設定)
var t = new DispatcherTimer(DispatcherPriority.SystemIdle);

// タイマーイベントの発生間隔を300ミリ秒に設定
t.Interval = TimeSpan.FromMilliseconds(300);

// タイマーイベントの定義
t.Tick += (sender, e) => {
// タイマーイベント発生時の処理をここに書く

// 現在の時分秒をテキストに設定
textBlock.Text = DateTime.Now.ToString("HH:mm:ss");
};

// 生成したタイマーを返す
return t;
}
}


タイマー生成メソッドの呼び出し処理追加

コンストラクタのInitializeComponentの後に、CreateTimerを呼び出して結果をtimer変数に入れる処理を書きます。

コンストラクタはクラス生成時に呼び出されます。

つまりMainWindowの初期処理です。

public MainWindow()

{
InitializeComponent();

// タイマー生成
timer = CreateTimer();
}

書き終わったらCreateTimerをマウスでポイントしてみてください。

メソッド定義と///で書いたコメントがポップアップで表示されます。

wbg2-19.png

timerの方もマウスでポイントするとコメント内容が表示されます。

ソースを読む助けになるので///コメント(ドキュメントコメント)は積極的に書きましょう。

wbg2-20.png

ここまでで、タイマーを生成する処理、タイマーが起動したら一定間隔で現在時刻を表示する処理が書けました。

最後にタイマーを起動する処理を書きます。

タイマー生成の後すぐに起動してもよいのですが、イベント処理の練習のため、時刻のテキストをクリックしたらタイマー起動するようにしてみます。


タイマー起動処理の追加

XAMLの方に戻り、TextBlockタグを選択してください。

画面デザイナの方で選択してもいいですが、画面が入り組んでくると目的のコントロールを選択しづらくなってくるのでXAMLのタグを選択した方が確実です。

wbg2-21.png

プロパティウィンドウの右上に稲妻のマークがあるのでクリックしてください。

TextBlockで使えるイベントの一覧が出てきます。

(前回は画面デザイナ上でボタンをダブルクリックしてイベント処理を書きましたが、もちろんボタンもこの方法で書けます。)

TextBlockにはClickイベントが無いので、MouseDownイベントを使うことにします。

MouseDownのテキストボックスをダブルクリックしてください。

イベントハンドラが自動的に作成されます。

テキストボックスに文字を直接打ち込んで任意の名前を付けることもできます。

イベントハンドラの中にtimer.Start();と入力してください。

wbg2-22.png


お掃除

最後に、コードビハインドに戻ってエディタ部分の適当な場所で右クリック、「usingの整理」 - 「usingの削除と並べ替え」を実行して、使っていないusing定義を消します。

ソースをすっきりさせたい人はやってください。

まだ色々コード追加する予定の人はそれが完全に終わってからの方がいいです。

wbg2-23.png

すっきり。

wbg2-24.png

最終的なXAMLも載せておきます。


MainWindow.xaml

<Window x:Class="WpfApplication2.MainWindow"

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApplication2"
mc:Ignorable="d"
Title="時計" Height="250" Width="525" ResizeMode="CanResizeWithGrip" ShowInTaskbar="False" Topmost="True">
<Grid>
<Viewbox>
<TextBlock x:Name="textBlock" Text="00:00:00" MouseDown="textBlock_MouseDown"/>
</Viewbox>

</Grid>
</Window>



動かしてみる

ツールバーで開始ボタンを押すとビルドされてプログラムが起動します。

wbg2-25.png

00:00:00の部分をマウスでクリックするとタイマーが動き出し、現在時刻が表示されるようになります。

wbg2-26.png

ウィンドウを拡大・縮小するとウィンドウサイズに合わせて時刻の文字サイズも変わります。

wbg2-27.png


配布するとき

Visual Studio上からでなく、普通にexeとして起動したい場合や、他の人に配布するときはReleaseビルドで作成したexeを使ってください。

DebugビルドからReleaseビルドに切り替えて、メニューの「ビルド」 - 「ソリューションのビルド」を実行します。

wbg2-28.png

ソリューションエクスプローラーでプロジェクトを右クリックし、「エクスプローラーでフォルダを開く」を選択します。

wbg2-29.png

bin\Releaseフォルダを開き、 【プロジェクト名】.exe を配布してください。

この例だと、WpfApplication2.exeです。

他のファイルは不要です。

wbg2-30.png

おしまい



参考サイト


< 前の記事   次の記事 >