<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>はらぺこ日誌 &#187; 活動記録</title>
	<atom:link href="https://blog.harapeko.jp/category/work-log/feed/" rel="self" type="application/rss+xml" />
	<link>https://blog.harapeko.jp</link>
	<description>株式会社はらぺこ 公式ブログ</description>
	<lastBuildDate>Mon, 30 Oct 2017 14:32:56 +0000</lastBuildDate>
	<language>ja</language>
		<sy:updatePeriod>hourly</sy:updatePeriod>
		<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.9.2</generator>
	<item>
		<title>第10期決算報告書を公開しました</title>
		<link>https://blog.harapeko.jp/2017/10/30/account2016/</link>
		<comments>https://blog.harapeko.jp/2017/10/30/account2016/#comments</comments>
		<pubDate>Mon, 30 Oct 2017 14:32:56 +0000</pubDate>
		<dc:creator><![CDATA[村山 俊之]]></dc:creator>
				<category><![CDATA[活動記録]]></category>
		<category><![CDATA[お知らせ]]></category>

		<guid isPermaLink="false">http://blog.harapeko.jp/?p=404</guid>
		<description><![CDATA[第10期決算報告書を公開しました。 今期については特にコメントすることはありません…。 しばらく Python [&#8230;]]]></description>
				<content:encoded><![CDATA[<p><a href="http://www.harapeko.jp/account/Statement_of_Accounts-2016_9-2017_8.pdf">第10期決算報告書</a>を公開しました。</p>
<p>今期については特にコメントすることはありません…。</p>
<p>しばらく Python ネタをちょこちょこと書いておりましたが、ここ最近は個人で受託した仕事で専らクローラ書いたり DB いじったりといったことをやっています。<br />
そのうち何かネタがまとまればこことかに書くつもりです…。</p>
<p>定時で上がれる現場はいいですな…。</p>
]]></content:encoded>
			<wfw:commentRss>https://blog.harapeko.jp/2017/10/30/account2016/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>第9期決算報告書を公開しました</title>
		<link>https://blog.harapeko.jp/2016/10/29/%e7%ac%ac9%e6%9c%9f%e6%b1%ba%e7%ae%97%e5%a0%b1%e5%91%8a%e6%9b%b8%e3%82%92%e5%85%ac%e9%96%8b%e3%81%97%e3%81%be%e3%81%97%e3%81%9f/</link>
		<comments>https://blog.harapeko.jp/2016/10/29/%e7%ac%ac9%e6%9c%9f%e6%b1%ba%e7%ae%97%e5%a0%b1%e5%91%8a%e6%9b%b8%e3%82%92%e5%85%ac%e9%96%8b%e3%81%97%e3%81%be%e3%81%97%e3%81%9f/#comments</comments>
		<pubDate>Sat, 29 Oct 2016 06:38:31 +0000</pubDate>
		<dc:creator><![CDATA[村山 俊之]]></dc:creator>
				<category><![CDATA[活動記録]]></category>
		<category><![CDATA[お知らせ]]></category>
		<category><![CDATA[決算]]></category>

		<guid isPermaLink="false">http://blog.harapeko.jp/?p=383</guid>
		<description><![CDATA[第9期決算報告書を公開しました 今期は某所とのサポート契約でわずかながら売上を立てていたものの、事実上営業活動 [&#8230;]]]></description>
				<content:encoded><![CDATA[<p><a href="http://www.harapeko.jp/account/Statement_of_Accounts-2015_9-2016_8.pdf">第9期決算報告書</a>を公開しました</p>
<p>今期は某所とのサポート契約でわずかながら売上を立てていたものの、事実上営業活動は個人にて行っていたのみであり、法人としての活動実績はほとんどありません。ブログも更新できてないですしね…。</p>
<p>近況ですが、まず個人的なところで、今年の 1月に家族が増えました。今後は家族のために、極力安定的に稼げる手立てを模索していくことになると思っています…。</p>
<p>最近思うのは、会社を立ち上げるのは明確な事業計画が出来上がってからでも遅くはなかったのではないかということです。そのための準備をできる時間的猶予が欲しいのですが… その捻出のための工夫も考えていくつもりでいます。</p>
]]></content:encoded>
			<wfw:commentRss>https://blog.harapeko.jp/2016/10/29/%e7%ac%ac9%e6%9c%9f%e6%b1%ba%e7%ae%97%e5%a0%b1%e5%91%8a%e6%9b%b8%e3%82%92%e5%85%ac%e9%96%8b%e3%81%97%e3%81%be%e3%81%97%e3%81%9f/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>第8期決算報告書を公開しました</title>
		<link>https://blog.harapeko.jp/2015/10/24/account2014/</link>
		<comments>https://blog.harapeko.jp/2015/10/24/account2014/#comments</comments>
		<pubDate>Sat, 24 Oct 2015 06:14:33 +0000</pubDate>
		<dc:creator><![CDATA[村山 俊之]]></dc:creator>
				<category><![CDATA[活動記録]]></category>
		<category><![CDATA[お知らせ]]></category>
		<category><![CDATA[仕事]]></category>

		<guid isPermaLink="false">http://blog.harapeko.jp/?p=380</guid>
		<description><![CDATA[第8期決算報告書を公開しました。前期も一応黒字です。 …前回のブログ更新も決算報告ですね… この1年、社長ブロ [&#8230;]]]></description>
				<content:encoded><![CDATA[<p><a href="http://www.harapeko.jp/account/Statement_of_Accounts-2014_9-2015_8.pdf">第8期決算報告書</a>を公開しました。前期も一応黒字です。</p>
<p>…前回のブログ更新も決算報告ですね… この1年、社長ブログ更新してなかったのか… orz</p>
<p>近況ですが、ここ最近の仕事はずっと ASP.NET MVC 関連のものです。但し、9月から、メインの取引先が変わっています。で、その取引先さんとは (諸事情により) 個人事業主として契約しております。つまり、今期から、会社としての売上は、(ほとんど) 立たなくなるということになります…。</p>
<p>私自身としては、会社の社長になることであるとか、会社を大きくすることであるとか、といったことを目的にしているわけではないので、それはどちらでも良いことではあるのですが。</p>
]]></content:encoded>
			<wfw:commentRss>https://blog.harapeko.jp/2015/10/24/account2014/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>第７期決算報告書を公開しました</title>
		<link>https://blog.harapeko.jp/2014/10/29/account2013/</link>
		<comments>https://blog.harapeko.jp/2014/10/29/account2013/#comments</comments>
		<pubDate>Wed, 29 Oct 2014 06:00:08 +0000</pubDate>
		<dc:creator><![CDATA[村山 俊之]]></dc:creator>
				<category><![CDATA[活動記録]]></category>
		<category><![CDATA[決算]]></category>

		<guid isPermaLink="false">http://blog.harapeko.jp/?p=377</guid>
		<description><![CDATA[第７期決算報告書を公開しました。 前期は一応まあまあの黒字でした。当面は同等の売上が立ち続ける見込みなので、今 [&#8230;]]]></description>
				<content:encoded><![CDATA[<p><a href="http://www.harapeko.jp/account/Statement_of_Accounts-2013_9-2014_8.pdf">第７期決算報告書</a>を公開しました。</p>
<p>前期は一応まあまあの黒字でした。当面は同等の売上が立ち続ける見込みなので、今期から役員報酬を計上しようかなと…</p>
<p>なんかもうちょっとまとまった売上が立つ仕事無いもんですかね(´・ω・｀)。</p>
]]></content:encoded>
			<wfw:commentRss>https://blog.harapeko.jp/2014/10/29/account2013/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Pimpl とかファクトリとか &#8211; C++ のための API デザイン</title>
		<link>https://blog.harapeko.jp/2014/06/19/pimpl-factory-apides/</link>
		<comments>https://blog.harapeko.jp/2014/06/19/pimpl-factory-apides/#comments</comments>
		<pubDate>Thu, 19 Jun 2014 05:53:55 +0000</pubDate>
		<dc:creator><![CDATA[村山 俊之]]></dc:creator>
				<category><![CDATA[技術メモ]]></category>
		<category><![CDATA[活動記録]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[C++11]]></category>
		<category><![CDATA[設計]]></category>

		<guid isPermaLink="false">http://blog.harapeko.jp/?p=304</guid>
		<description><![CDATA[otoco プロジェクトの開発に着手するにあたって、私はまだ C++ でのライブラリ開発を 1 からコーディネ [&#8230;]]]></description>
				<content:encoded><![CDATA[<p><a href="http://developer.harapeko.jp/trac/original/otoco">otoco プロジェクト</a>の開発に着手するにあたって、私はまだ C++ でのライブラリ開発を 1 からコーディネートした経験がなかったので、クロスプラットフォームに対応したライブラリ API の開発手法を学ぶ必要があると感じました。ちょうどいい感じの教材が割りと最近出ていたようで、早速購入し、勉強を進めています。</p>
<ul>
<li><a href ='http://www.amazon.co.jp/gp/search/ref=as_li_qf_sp_sr_il?ie=UTF8&#038;camp=247&#038;creative=1211&#038;index=aps&#038;keywords=C%2B%2B%20API%E3%83%87%E3%82%B6%E3%82%A4%E3%83%B3&#038;linkCode=as2&#038;tag=harapekoinc-22'>C++ APIデザイン<br />
<img src='http://ws-fe.amazon-adsystem.com/widgets/q?_encoding=UTF8&#038;ASIN=B00EYXMA6Q&#038;Format=_SL250_&#038;ID=AsinImage&#038;MarketPlace=JP&#038;ServiceVersion=20070822&#038;WS=1&#038;tag=harapekoinc-22' border='0' /></a></li>
</ul>
<p>C++11 についても若干触れられているようで (原著執筆当時はまだ C++0x と呼ばれていた模様…)、この手の教材の中では比較的情報が新しい方なんではないかと思われます。</p>
<p>実はこの本を買って勉強し始めたのはもう結構前 (確か前原にいた頃… 昨年の暮れ頃?) なのですが、ここしばらく本業やら引っ越しやらが忙しくてなかなか手を回せずにいたので、久しぶりの着手ということで、すでに履修していた第3章の、 Pimpl イディオムとファクトリメソッド辺りを復習してみました。<br />
<span id="more-304"></span><br />
今度こそ本腰を入れてちゃんとやろう、ということで、<a href="https://github.com/murachi/samples-for-blog/tree/master/c%2B%2B/api-design-for-c%2B%2B" title="samples-for-blog/c++/api-design-for-c++ at master · murachi/samples-for-blog">練習用に書いたサンプルプログラムは github に up しております</a>。 git の練習も兼ねているのですが…。</p>
<h3>Pimpl イディオム</h3>
<p>C++ でライブラリを実装するのに際して最も基本的とも言うべきテクニックです。 2章の中で、優れた API の特徴について議論されていますが、その中でも Pimpl イディオムは、プラットフォーム独立性を高める働きと、結合度を削減する働きを担っています。本書のサンプルではタイマーを取り上げ、 Unix の getTimeOfDay(2) システムコールと Win32 の <code>GetTickCount()</code> API の両方に対応する場合に、 Pimpl イディオムを用いて実装の詳細をヘッダーファイルから <code>.cpp</code> ファイルへ隠すというものでした。</p>
<ul>
<li><a href="https://github.com/murachi/samples-for-blog/tree/master/c%2B%2B/api-design-for-c%2B%2B/ch03-pattern/pimpl" title="samples-for-blog/c++/api-design-for-c++/ch03-pattern/pimpl at master · murachi/samples-for-blog">Pimpl イディオムのサンプルプログラム</a></li>
</ul>
<p>私が書いたサンプルもほぼ同内容です (メインルーチンはお馴染みの? あほプログラムでやんす)。強いて違いを言えば、 Pimpl を <code>std::unique_ptr</code> に突っ込んでいること (本書では <code>boost::scoped_ptr</code> を採用していました) ぐらいでしょうか。</p>
<h3>ファクトリメソッド</h3>
<p>本書では Pimpl イディオムの次にシングルトンパターンを解説していますが、今回はここは一旦飛ばして (書かれていることは有用なので、目を通すことはおすすめします)、ファクトリメソッドの方をさらってみました。</p>
<p>本書で紹介されているファクトリメソッドは、 GoF のファクトリメソッドパターンとは若干異なるようで、 Creator の継承と Product の継承を連動させて云々、というものではなく、単に値による指定で生成するオブジェクトの種類を切り替えるという類のもののようでした。これはこれで、例えばプラグインの実装なんかでは役に立ちそうなテクニックだとは思います。</p>
<ul>
<li><a href="https://github.com/murachi/samples-for-blog/tree/master/c%2B%2B/api-design-for-c%2B%2B/ch03-pattern/factory" title="samples-for-blog/c++/api-design-for-c++/ch03-pattern/factory at master · murachi/samples-for-blog">ファクトリメソッドのサンプルプログラム</a></li>
</ul>
<p>拡張可能なファクトリの応用として、ファクトリ登録を生成されるオブジェクトのクラス毎に行うようにし、 Product の追加が行いやすいような設計にしてみました。この用途に限れば登録解除は不要だろうということで、登録用のメソッドのみ用意。ファクトリ名とコールバックの保存には、グローバル変数<strong>ではなく</strong>、関数内 <code>static</code> 変数として用意した <code>std::unordered_map</code> に格納することで、コンパイル単位をまたいだ非ローカル静的オブジェクトの初期化順に伴うSEGVりを回避しています (この辺のことはそれこそ本書のシングルトンの項にて、 Scott Meyers の言葉を引用しつつ説明されています)。</p>
<p>また、せっかくなので極力 Pimpl を用いるようにしてみました。プラットフォーム独立性も重要ですが、それを考慮する必要のない場面でも、 <code>private</code> メソッドの追加・変更に伴う再コンパイルを気にする必要がなくなることによるメンテナンス性の向上 (修正・改変・リファクタリングのやりやすさ) は非常に重要です。今回作った中では、特に <code>Base64Converter</code> クラスの実装がまぁまぁいいサンプルになったんじゃないかと思います (…<code>Base64Map</code>クラスも <code>.cpp</code> ファイルの中に隠しちゃってもよかったかもなぁ…)。</p>
<p>今回はここまで。次回があれば、今度はラッピングパターン、オブザーバーパターンあたりをさらえればと思います。</p>
]]></content:encoded>
			<wfw:commentRss>https://blog.harapeko.jp/2014/06/19/pimpl-factory-apides/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>事務所移転しました</title>
		<link>https://blog.harapeko.jp/2014/05/26/office-moving/</link>
		<comments>https://blog.harapeko.jp/2014/05/26/office-moving/#comments</comments>
		<pubDate>Mon, 26 May 2014 00:49:08 +0000</pubDate>
		<dc:creator><![CDATA[村山 俊之]]></dc:creator>
				<category><![CDATA[活動記録]]></category>

		<guid isPermaLink="false">http://blog.harapeko.jp/?p=302</guid>
		<description><![CDATA[今更のご報告で恐縮なのですが…。 5月1日付けで、事務所を移転いたしました。新しい住所、及び電話番号を、会社サ [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>今更のご報告で恐縮なのですが…。</p>
<p>5月1日付けで、事務所を移転いたしました。新しい住所、及び電話番号を、会社サイトの<a href="http://www.harapeko.jp/summary.php">会社概要のページ</a>に反映いたしましたので、これからご連絡いただける方はご注意ください。</p>
<p>これまでは自宅兼事務所という形で運営しておりましたが、今回は諸々の事情が有りまして、自宅とは別に独立した事務所を設置しました (とは言っても1Rマンションですが…)。最寄り駅も千葉駅ということで、これまでよりかえって都心から離れてしまいましたが… 環境的にはかなり大きく変わったということも有りますので、これよりまた心機一転、仕事に勤しんでいきたいと思います。</p>
<p>今後ともご贔屓に…。</p>
]]></content:encoded>
			<wfw:commentRss>https://blog.harapeko.jp/2014/05/26/office-moving/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Boost.勉強会 #14 に行ってきました</title>
		<link>https://blog.harapeko.jp/2014/03/04/boost-study-1/</link>
		<comments>https://blog.harapeko.jp/2014/03/04/boost-study-1/#comments</comments>
		<pubDate>Tue, 04 Mar 2014 04:36:38 +0000</pubDate>
		<dc:creator><![CDATA[村山 俊之]]></dc:creator>
				<category><![CDATA[活動記録]]></category>
		<category><![CDATA[Boost]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[講習会]]></category>

		<guid isPermaLink="false">http://blog.harapeko.jp/?p=300</guid>
		<description><![CDATA[Boost.勉強会 #14 東京 &#8211; boostjp ヲレが書いたメモ というわけで boostj [&#8230;]]]></description>
				<content:encoded><![CDATA[<ul>
<li><a href="https://sites.google.com/site/boostjp/study_meeting/study14">Boost.勉強会 #14 東京 &#8211; boostjp</a></li>
<li><a href="http://developer.harapeko.jp/trac/original/ideanote/wiki/HowTo/BoostStudy14" title="HowTo/BoostStudy14 – Idea note">ヲレが書いたメモ</a>
</ul>
<p>というわけで boostjp 書記担当(?)の @T_MURACHI でございます。ご報告遅れましたが、 3/1 に開催された Boost.勉強会 #14 に行ってきました。過去ログ見る限り #4 以来なので 3年ぶりですか…。なんかもうそろそろコンパイラ的に C++11 使えるのも当たり前になってきて当時に比べてもだいぶいい時代になったなぁとか思ってみたり (M$ 除く)。</p>
<p>内容についてはメモに書いた以上のことを語り尽くせる自信がないので、以下、感想などを思いつきで綴ってみます…。</p>
<ul>
<li>並列処理に関連する話題を取り上げた話が多かったように思います。トレンドというよりは、プロセッサなどのハードの進化の方向がもう完全にこっちに移行していっているが故の必然、といった感じなんですかね。GPGPU に関して言えば応用カテゴリはまだまだ限られている模様ですが…。</li>
<li>cpprefjp の github 連携のための涙ぐましい… という程でもないとは思うんですが^^;、Google Sites なんて使い始めちゃったのが運の尽きっちゃあ運の尽きだったのかなぁとは… でも用意されたものにうまいこと順応できるよう対応する能力ってのはこのギョーカイで仕事やってる上で絶対重宝されると思うので、そういう意味でも良い経験をされたんじゃないかなと思います。
<ul>
<li>ていうか @melponn さんかわいい。</li>
</ul>
</li>
<li>聴衆の食付きは glfw3 を使った GUI フレームワークの話が一番良かったように思います。なんだかんだ言ってみんなビジュアルグリグリ動かす系好きなんだなぁと…。 @hira_kuni_45 さん経験豊富そうで尊敬します… OpenGL 大好きで GCC 大好きで Unix ライクなのの方が好きそうなのにメインの開発環境が MinGW て… なんか某 R 社 (コピー機とか作ってる方) で働いてた時もそういう感じの方結構いらっさったような…</li>
<li>その他、グラフアルゴリズムの話とか、 C# でやってることを C++ で実装したら…の話とか、どれも非常に興味深いお話でした。面白かった。</li>
<li>会場には<a href="http://cpplover.blogspot.jp/" title="本の虫">江添さん</a>もいらっさってましたね。ドワンゴステッカー配り始めたところで確信しましたが… 思ってたよりもなんだかずっと元気なちっさいオッサンって感じでした^^;。 @cpp_akira さんと C++WG の主査がどうのこうのとかで話をしていて平行線を辿ったりとかしていたのを見るにつけ、 C++ 標準化界隈も一枚岩じゃないんだなぁとか思ってみたり…</li>
</ul>
<p>そんなこんなで、割とぶっ通しの 8時間。流石に疲れました…。参加された皆様も本当にお疲れ様でした。</p>
]]></content:encoded>
			<wfw:commentRss>https://blog.harapeko.jp/2014/03/04/boost-study-1/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>第6期決算報告と移転のお知らせ</title>
		<link>https://blog.harapeko.jp/2013/11/07/account-6th/</link>
		<comments>https://blog.harapeko.jp/2013/11/07/account-6th/#comments</comments>
		<pubDate>Thu, 07 Nov 2013 03:03:25 +0000</pubDate>
		<dc:creator><![CDATA[村山 俊之]]></dc:creator>
				<category><![CDATA[活動記録]]></category>
		<category><![CDATA[お知らせ]]></category>
		<category><![CDATA[決算]]></category>

		<guid isPermaLink="false">http://blog.harapeko.jp/?p=297</guid>
		<description><![CDATA[第6期 決算報告書 (2012年9月～2013年8月) 昨期は特に主だった売り上げもなく、赤字決算に終わりまし [&#8230;]]]></description>
				<content:encoded><![CDATA[<ul>
<li><a href="http://www.harapeko.jp/account/Statement_of_Accounts-2012_9-2013_8.pdf">第6期 決算報告書 (2012年9月～2013年8月)</a></li>
</ul>
<p>昨期は特に主だった売り上げもなく、赤字決算に終わりました…。</p>
<p>ただ、今期はすでにいくらか売り上げを確保しておりますので、これまでの青色欠損分をいくらか取り返すことは出来そうです。(志低いな…)</p>
<p>それともう一つ。自宅の引っ越しに伴い、弊社住所も移転となりましたのでお知らせします。<br />
新住所とアクセスについては、すでに<a href="http://www.harapeko.jp/summary.php">会社概要のページ</a>にて内容を更新済みです。</p>
]]></content:encoded>
			<wfw:commentRss>https://blog.harapeko.jp/2013/11/07/account-6th/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>WPF と MVVM で時刻入力コントロール</title>
		<link>https://blog.harapeko.jp/2013/03/01/wpf-mvvm-time-input-control/</link>
		<comments>https://blog.harapeko.jp/2013/03/01/wpf-mvvm-time-input-control/#comments</comments>
		<pubDate>Thu, 28 Feb 2013 21:27:51 +0000</pubDate>
		<dc:creator><![CDATA[村山 俊之]]></dc:creator>
				<category><![CDATA[技術メモ]]></category>
		<category><![CDATA[活動記録]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[Csharp]]></category>
		<category><![CDATA[MVVM]]></category>
		<category><![CDATA[WPF]]></category>

		<guid isPermaLink="false">http://blog.harapeko.jp/?p=277</guid>
		<description><![CDATA[ご無沙汰しております。 会社としての仕事がなかなか収入につながらないため、昨年の秋から個人事業主として某所で頂 [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>ご無沙汰しております。</p>
<p>会社としての仕事がなかなか収入につながらないため、昨年の秋から個人事業主として某所で頂いた設計の仕事に従事しています。当初は 1～2ヶ月程度の短期の仕事として契約しておりましたが、のっぴきならない諸処の事情 <tt>(^-^;</tt> により、最低でも今月末まで、できればその後の開発の方にも～、ってな感じでなにげに長引きそうであります。</p>
<p>お金がないので (泣、仕事があること自体はありがたいことではあります… 残業続きですでにへとへとですが。</p>
<p>で、そのお仕事なのですが、 Windows 向けの業務アプリでありまして、開発には C# (Visual Studio 2010 / .NET 4.0) と WPF を利用することが決まっております。我々設計部隊も、画面イメージ作成のために XAML を書いたり、レビューの際の説明のために簡単な制御ロジックを書いたりもしています。</p>
<p>まぁ画面作りに時間をかけてばかりも居られないので、たいていの人は WYSIWYG の XAML エディタで枠だけ書いて終わり、制御ロジックを書くにしても code behind に直接書くだけなのですが (そもそも WPF とか知らん、さらにいえばプログラミング自体ほとんど経験無いって人も少なくなく…)、開発工程にも関わる可能性があり、なおかつ WPF なんて現場ではほとんど使われていないために経験がある技術者が見つかりにくいという中で、いい機会なのでこの際勉強もかねて MVVM スタイルでの記述を心がけるようにしていたりするわけです。割と楽しいし。</p>
<p>そんなわけで、当ブログではこれからしばらくの間、 WPF と MVVM 関連のネタを綴っていくことにしようかと思っております。どうぞお付き合いくださいませ…。<br />
<span id="more-277"></span></p>
<h3>DatePicker はあるのに…</h3>
<p>そんなわけで、今回は時刻を入力するコントロールの作り方について考えてみることにします。ありがちな課題だとは思うのですが、日付の入力は DatePicker があるのに時刻を入力するための適当なコントロールが見当たらなくてどうしようか、といった場合に、既製品をどこかから仕入れて組み込んでしまえばいいのですが、ライセンス管理がどうこうだの、バグがあった場合にどこまでサポートしてもらえるだの、それはそれで面倒なことも少なくないので、であれば適当に仕様を決めて作ってしまうのも手かなとか思ったりもするわけです。このくらいであればそんなに難しくもないですし。</p>
<p>結論から (?) 言ってしまうと、できあがったサンプルプログラムを <a href="https://github.com/murachi/samples-for-blog/tree/master/wpf/TimeInputSample" title="amples-for-blog/wpf/TimeInputSample at master ・ murachi/samples-for-blog ・ GitHub">GitHub 上</a>で公開しています。何気に Git の練習も兼ねているという… <tt>(^^;</tt></p>
<p><a href="http://blog.harapeko.jp/wp-content/uploads/2013/02/20130202-wpf-fig01.png"><img src="http://blog.harapeko.jp/wp-content/uploads/2013/02/20130202-wpf-fig01.png" alt="WPF + MVVM で時刻入力コントロール" title="WPF + MVVM で時刻入力コントロール" width="525" height="350" class="aligncenter size-full wp-image-268" /></a></p>
<h3>とりあえず設計</h3>
<p>あくまでサンプルなのでそんなに厳密な話はするつもりはないのですが、おおざっぱに仕様を決めておきましょう。</p>
<ul>
<li>入力するのは時と分だけとします。秒は扱いません。</li>
<li><q><code>hh:mm</code></q>形式で表示します。但しコロンは固定、時と分でテキストボックスが分かれているイメージです。また、分は 2桁固定で 0 パディングします (時は 0 パディングしません)。</li>
<li>時、分は普通にテキスト入力させます。スピンボタンとかは設けません。</li>
<li>時、分のテキストボックスは、どちらも 2文字までしか入力を受け付けません。</li>
<li>時、分のテキストボックスは、どちらもフォーカスを抜けた段階でバリデーションを行います。受け付けられない値が入力された場合は、元々入力されていた値 (空欄だった場合は空欄) に戻します。
<ul>
<li>空欄にすることは可能とします。</li>
</ul>
</li>
<li>ちょっと細かい話ですが、時、または分のテキストボックスは、フォーカスを受け取ったら中身の数字を全選択状態にします。</li>
<li>さらに細かい話ですが、分が空欄の状態で、時に有効な値が入力された (バリデーションをパスした) ら、その時点で時に「00」を設定します。利便性のための仕様ですね。</li>
<li>時、分の両方に有効な値が入力されている場合のみ、「値がある」状態とします。それ以外の場合は「値がない」状態として扱います。</li>
</ul>
<h3>開発環境</h3>
<p>Visual Studio は製品版である必要はありません。ていうかそんなお高いもの弊社の経済事情では調達できません <tt>(T-T)</tt>。普通に <a href="http://www.microsoft.com/visualstudio/jpn/downloads#d-csharp-2010-express">Visual C# 2010 Express</a> を使いましょう。</p>
<p>※仕事の関係上、 Visual Studio 2012 / .NET 4.5 はノーチェックです。サンプルもあくまで 2010 をターゲットに作ってます。バージョンの変わり目っていろいろと面倒ですね… (&#8216;A`)</p>
<p>それから、 MVVM スタイルでのプログラミングと言うことで、 Expression Blend SDK が必須となっております (Expression Blend 自体が必要という話ではありません… あった方がいいんでしょうけど)。今回のサンプルでも使っているので、以下よりダウンロードしてインストールしてください。</p>
<ul>
<li><a href="http://www.microsoft.com/ja-jp/download/details.aspx?id=10801">Expression Blend 4 SDK for .NET 4 &#8211; Microsoft Download Center</a></li>
</ul>
<h3>ソリューションとかプロジェクトとか名前空間とか</h3>
<p>ありがちな手法としてよく紹介されるのは、 Model、 View、 ViewModel の 3つに名前空間を分けましょう、といってフォルダを 3つ掘らせる (さらに Common とか掘らせちゃったりする) やり方だと思うのですが、 Model を単体テストさせることを念頭に置くのであれば、個人的には Model は名前空間ではなくてプロジェクト自体を分けちゃった方がいいんじゃないかとか思ったりするわけです。</p>
<p>そんなわけで、今回のソリューションの構成は最終的には以下のような感じになりました。</p>
<table>
<caption>TimeInputSample ソリューションの構成</caption>
<tr>
<th>プロジェクト</th>
<th>名前空間</th>
<th>説明</th>
</tr>
<tr>
<td rowspan="3">TimeInputSample</td>
<td>TimeInputSample</td>
<td>形骸化するｗメイン部分</td>
</tr>
<tr>
<td>TimeInputSample.View</td>
<td>View (XAML 置き場)</td>
</tr>
<tr>
<td>TimeInputSample.ViewModel</td>
<td>ViewModel やその他の制御ロジック</td>
</tr>
<tr>
<td>TimeInputModel</td>
<td>TimeInputModel</td>
<td>Model</td>
</tr>
<tr>
<td>TestTimeInputModel</td>
<td>TestTimeInputModel</td>
<td>Model 用の単体テスト</td>
</tr>
</table>
<p>ちなみに今回は面倒なので <code>MainWindow.xaml</code> は名前空間 <code>TimeInputSample</code> から移動してません。本当はこれも <code>TimeInputSample.View</code> の配下に移動すべきなんでしょうが…。</p>
<p>で、「最終的に」と書きましたが、何でかというと、この最終形態はあくまで実際に動いているところを見せるための使用例に過ぎず、今回のトピックのメインはあくまで時刻入力コントロールの実装方法だからです。</p>
<h3>時刻入力コントロールの実装</h3>
<h4>XAML</h4>
<p>まず、プロジェクト上にユーザーコントロールを新規追加すると、デフォルトでは <code>&lt;UserControl&gt;</code> 要素に <code>d:DesignHeight</code> やら <code>d:DesignWidth</code> やらとありますが、これらは WYSIWYG エディタ上での表示の大きさが設定できるだけみたいです。固定サイズのウィンドウやコントロールに対して WYSIWYG 操作で編集する文には便利なんですが、今回は不要なので取っ払ってしまいましょう。</p>
<p>とりあえず大枠で見た目を作ってしまいます。だいたい以下のようなコードになります。</p>
<pre>
&lt;UserControl x:Class=&quot;TimeInputSample.View.TimeInputControl&quot;
             xmlns=&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;
             xmlns:x=&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;
             xmlns:mc=&quot;http://schemas.openxmlformats.org/markup-compatibility/2006&quot;&gt;
    &lt;UserControl.Resources&gt;
        &lt;ResourceDictionary Source=&quot;CommonResources.xaml&quot; /&gt;
    &lt;/UserControl.Resources&gt;
    &lt;Grid&gt;
        &lt;Grid.Resources&gt;
            &lt;Style x:Key=&quot;TimeInputTextBox&quot; TargetType=&quot;TextBox&quot; BasedOn=&quot;{StaticResource DigitTextBox}&quot;&gt;
                &lt;Setter Property=&quot;Background&quot; Value=&quot;Transparent&quot; /&gt;
                &lt;Setter Property=&quot;BorderThickness&quot; Value=&quot;0&quot; /&gt;
                &lt;Setter Property=&quot;Padding&quot; Value=&quot;0&quot; /&gt;
                &lt;Setter Property=&quot;Width&quot; Value=&quot;26&quot; /&gt;
                &lt;Setter Property=&quot;Height&quot; Value=&quot;24&quot; /&gt;
                &lt;Setter Property=&quot;MaxLength&quot; Value=&quot;2&quot; /&gt;
            &lt;/Style&gt;
        &lt;/Grid.Resources&gt;
        &lt;Grid.ColumnDefinitions&gt;
            &lt;ColumnDefinition Width=&quot;Auto&quot; /&gt;
            &lt;ColumnDefinition Width=&quot;Auto&quot; /&gt;
            &lt;ColumnDefinition Width=&quot;Auto&quot; /&gt;
        &lt;/Grid.ColumnDefinitions&gt;
        &lt;Label Background=&quot;White&quot; BorderBrush=&quot;#555&quot; BorderThickness=&quot;1,2,1,1&quot; Grid.ColumnSpan=&quot;3&quot; /&gt;
        &lt;TextBox Text=&quot;{Binding Path=HourText}&quot; Grid.Column=&quot;0&quot; Style=&quot;{StaticResource TimeInputTextBox}&quot; /&gt;
        &lt;Label Content=&quot;:&quot; Margin=&quot;4,0&quot; Padding=&quot;0&quot; Grid.Column=&quot;1&quot; /&gt;
        &lt;TextBox Text=&quot;{Binding Path=MinuteText}&quot; Grid.Column=&quot;2&quot; Style=&quot;{StaticResource TimeInputTextBox}&quot; /&gt;
    &lt;/Grid&gt;
&lt;/UserControl&gt;
</pre>
<p>外枠の見た目は <code>Label</code> を使っています。 <code>Rectangle</code> だと <code>BorderThickness</code> が <code>double</code> 型で、上下左右同じ太さにしかできないからです。</p>
<p>時、分を入力する 2つのテキストボックスは、枠を消し、背景色を透明にした上で、最大 2文字しか入力できないようにしてあります。こうした見た目などの補助的な属性はすべて Style として設定するようにしてみました。ちなみにベースになるスタイルはリソースディクショナリとして別ファイルで記述しています。</p>
<p><code>Grid.ColumnDefinitions</code> は、グリッドの列を定義します。ここでグリッドの列を分け、配下のコントロール毎に添付属性を使って、配置する列番号を <code>Grid.Column</code> で指定したり、列をまたぐ数を <code>Grid.ColumnSpan</code> で指定したりすることができます。</p>
<h4>ViewModel</h4>
<p>あくまでコントロールとして作るので、 ViewModel とは言っても、最初から View に割り当てられているのではなく、そのコントロールを配下にもつコンテナとなるウィンドウやコントロールの制御ロジック上でバインドするデータとして使うことを想定します。</p>
<p>表示上では数字以外の文字列を入力されたり、そも分は 0パディング表示しなければいけなかったりするので、時、分のテキストボックスにバインドするデータは <code>string</code> 型である必要があります。その一方で、制御ロジック上では時も分も <code>int</code> 値で扱えないと不便ですし、日付の <code>DateTime</code> に時刻を混ぜ合わせるような処理も欲しいところです。</p>
<pre>
    /// 時刻入力コントロール用のデータオブジェクトクラス。
    public class TimeInputControlData : ViewModelBase
    {
        /// 時刻の時。
        public int? Hour
        {
            // ...
        }

        /// 時刻の分。
        public int? Minute
        {
            // ...
        }

        /// 時刻の時の文字列表現。
        public string HourText
        {
            // ...
        }

        /// 時刻の分の文字列表現。
        public string MinuteText
        {
            // ...
        }

        /// 入力済みチェック。
        public bool HasValue
        {
            // ...
        }

        /// 日付に時刻を加えて日時に変換する。
        public DateTime? BlendWithDate(DateTime? date)
        {
            // ...
        }
    }
</pre>
<p>必要になるアクセサ、メソッドはざっとこんなところでしょうか。</p>
<p><code>ViewModelBase</code> というクラスを継承していますが、これは WPF で View にバインドするデータを制御ロジック込みのオブジェクトとして定義したい場合に実装すべき機能をまとめたものです。<a href="https://github.com/murachi/samples-for-blog/blob/master/wpf/TimeInputSample/TimeInputSample/ViewModel/ViewModelBase.cs" title="samples-for-blog/wpf/TimeInputSample/TimeInputSample/ViewModel/ViewModelBase.cs at master ・ murachi/samples-for-blog ・ GitHub">実装は至ってシンプル</a>で、単に <a href="http://msdn.microsoft.com/ja-jp/library/ms133020%28v=vs.100%29.aspx">System.ComponentModel.INotifyPropertyChanged</a> インタフェースを実装し、 View に関連づけられたプロパティの更新イベントを発生させるためのメソッド <code>NotifyPropertyChanged()</code> を用意しているだけです。</p>
<h4>入力とバリデーション</h4>
<p>時分の時の入力について考えてみましょう。ここで View に関連づけるプロパティは <code>HourText</code> の方ですが、制御ロジック側からのアクセスを考えると、 <code>int</code> 値として直接設定ができた方が何かとはかどりそうです。そこで、まずは <code>Hour</code> プロパティへの操作を実装してみます。</p>
<pre>
using System.Diagnostics;

    public class TimeInputControlData : ViewModelBase
    {
        private int? hour_val;

        public int? Hour
        {
            get { return hour_val; }
            set
            {
                Debug.Assert(!value.HasValue || 0 &lt;= value &#038;&#038; value &lt; 24);
                hour_val = value;
                NotifyPropertyChanged(&quot;HourText&quot;);
            }
        }

        // ...
</pre>
<p><code>Hour</code> プロパティに触れるのは制御ロジックだけで、ユーザー入力がここに直接入ってくるわけではない、というスタンスなので、ここでの Validation は単に Assertion としての扱いとなっています (さすがに手抜きに過ぎるかもですが…)。</p>
<p>View に関連づけているのはあくまで <code>HourText</code> プロパティなので、 <code>NotifyPropertyChanged()</code> メソッドに渡す「表示を更新すべきプロパティの名前」も <code>Hour</code> ではなく <code>HourText</code> ということになります。</p>
<p>ちなみに <code>Hour</code> プロパティも <code>hour_val</code> コンテナも、型は <code>int</code> ではなく <code>int?</code> 、すなわち <code>Nullable&lt;int&gt;</code> としています。これは、このコントロールが空欄の場合もあり得るためです。つまり、すでに存在する時刻入力コントロールに対して、制御ロジック側から表示を空欄にしたい場合は、以下のように書けばいい、ということになります。</p>
<pre>
    // 時刻入力コントロールにバインドするプロパティ
    TimeInputControlData TimeInput { get; private set; }

    // 時刻入力を空欄にする
    private void ResetTime()
    {
        TimeInput.Hour = TimeInput.Minute = null;
    }
</pre>
<p>さて、値の設定と表示への反映の仕組みはできあがったので、 <code>HourText</code> プロパティはこれを利用して実装することができます。ユーザー入力を扱わなければならない <code>HourText</code> の処理はこれよりやや複雑になります。</p>
<pre>
        public string HourText
        {
            get { return hour_val.HasValue ? hour_val.Value.ToString() : null; }
            set
            {
                // 空欄にされた場合
                if (value == null || value == "")
                {
                    Hour = null;
                    return;
                }
                // 入力のバリデーション
                int hour;
                if (int.TryParse(value, out hour) &#038;&#038; 0 <= hour &#038;&#038; hour < 24)
                {
                    Hour = hour;
                    // 時分の分が空欄なら、ここで "00" を設定する
                    if (!minute_val.HasValue)
                    {
                        Minute = 0;
                    }
                }
            }
        }
</pre>
<p><code>HourText</code> の中では、値の設定で <code>hour_val</code> コンテナ直接代入するのではなく、 <code>Hour</code> プロパティに代入するようにしています。こうすることで、 <code>Hour</code> プロパティ側で <code>NotifyPropertyChanged()</code> メソッドを呼んでくれるので、 View の表示もしっかり更新されるというわけです。反面、ユーザーが数字以外の文字や、 99 などのあり得ない値を入力してきた場合、 <code>Hour</code> への代入は発生しません。この場合、変更されなかった <code>hour_val</code> コンテナがもつ元々の値で表示が更新されます。たとえば、元々 "3" が入っていたところに "33" と入力しても、フォーカスが離れた途端に "3" に戻ってくれるということです。</p>
<p><code>Minute</code> と <code>MinuteText</code> もだいたい似たような感じで実装します。ここでは説明を割愛します。</p>
<h4>フォーカスを受け取ったら全選択</h4>
<p>データバインディング周りはこんなもんなので、あとは View のさらに細かい制御です。ここまでで、時刻の時を先に入力すると、分に勝手に「00」が入るようにしてあります。ここでさらに、時を入力した後に Tab キーでフォーカスを分に移すと分の「00」が全選択状態になるようにしてあると、分の書き換えも容易にできて便利かも知れません。</p>
<p>そこで (ちゃんと仕様にも書いてますが)、時、分の入力欄はフォーカスを受け取ったら全選択するように実装してみることにします。</p>
<p>この手の処理はさすがにコントロールのイベントに頼る必要があります。初めてのイベントドリブンプログラミングです。しかしそのためだけにコードビハインドを使うのはさすがにちょっとダサイです。そこで、 Expression SDK によってサポートされる Behavior や TriggerAction の利用を検討してみることにします。</p>
<ul>
<li><a href="http://code.msdn.microsoft.com/windowsdesktop/Behavior-beae13a6">Behavior入門 言語: C# Visual Studio 2010 用</a></li>
</ul>
<p>今回は単にコントロールのイベントと View Model の Command を結びつけられれば十分なので、 TriggerAction を利用することにします。 Behavior や TriggerAction を利用するための準備については、上記サイトに詳しく書かれていますのでそちらを参照ください。要約するとこんな感じです。</p>
<ol>
<li>View および View Model があるプロジェクトの「参照設定」に、以下のアセンブリを追加する。
<ul>
<li>System.Windows.Interactivity</li>
<li>Microsoft.Expression.Interactions</li>
</ul>
</li>
<li>Behavior や TriggerAction を利用する UI の XAML ファイルにて、先頭のタグにおける名前空間の宣言部分に、以下の名前空間の宣言を書き加える。
<pre>
             xmlns:i=&quot;http://schemas.microsoft.com/expression/2010/interactivity&quot;
             xmlns:ei=&quot;http://schemas.microsoft.com/expression/2010/interactions&quot;
</pre>
</li>
</ol>
<p>次に XAML ファイルにて、時、分のテキストボックスに、 TriggerAction を追加します。ざっとこんな感じになります。</p>
<pre>
        &lt;TextBox Text=&quot;{Binding Path=HourText}&quot; Grid.Column=&quot;0&quot; Style=&quot;{StaticResource TimeInputTextBox}&quot;&gt;
            &lt;i:Interaction.Triggers&gt;
                &lt;i:EventTrigger EventName=&quot;GotFocus&quot;&gt;
                    &lt;i:InvokeCommandAction Command=&quot;{Binding Path=GotFocusCommand}&quot;
                                           CommandParameter=&quot;{Binding RelativeSource={RelativeSource FindAncestor,
                        AncestorType=TextBox}}&quot; /&gt;
                &lt;/i:EventTrigger&gt;
            &lt;/i:Interaction.Triggers&gt;
        &lt;/TextBox&gt;
        &lt;Label Content=&quot;:&quot; Margin=&quot;4,0&quot; Padding=&quot;0&quot; Grid.Column=&quot;1&quot; /&gt;
        &lt;TextBox Text=&quot;{Binding Path=MinuteText}&quot; Grid.Column=&quot;2&quot; Style=&quot;{StaticResource TimeInputTextBox}&quot;&gt;
            &lt;i:Interaction.Triggers&gt;
                &lt;i:EventTrigger EventName=&quot;GotFocus&quot;&gt;
                    &lt;i:InvokeCommandAction Command=&quot;{Binding Path=GotFocusCommand}&quot;
                                           CommandParameter=&quot;{Binding RelativeSource={RelativeSource FindAncestor,
                        AncestorType=TextBox}}&quot; /&gt;
                &lt;/i:EventTrigger&gt;
            &lt;/i:Interaction.Triggers&gt;
        &lt;/TextBox&gt;
</pre>
<p>これで、各テキストボックスの <code>GotFocus</code> イベントに、 <code>GotFocusCommand</code> という名前のコマンドを関連づけることができました。今回は <code>CommandParameter</code> の記述がポイントで、このバインディングでコマンドに渡されるパラメータは、まさにこの TriggerAction を設定しているテキストボックスオブジェクト自身です。</p>
<p><code>GotFocusCommand</code> は、渡されるパラメータがテキストボックスオブジェクトである想定で実装します。まず、パラメータが本当にテキストボックスオブジェクトかどうかを実行可否の判断材料として記述し、</p>
<pre>
using System.Windows.Controls;  // 忘れずに。

// ...

        private bool CanGotFocus(object parameter)
        {
            return parameter is TextBox;
        }
</pre>
<p>そして実行処理ではそのテキストボックスであるパラメータに対して全選択を行うメソッドの呼び出しを記述します。</p>
<pre>
        private void OnGotFocus(object parameter)
        {
            var target = parameter as TextBox;
            target.SelectAll();
        }
</pre>
<p>あとは、これらのメソッドをデリゲートとして設定したカスタムコマンドを <code>GotFocusCommand</code> コマンドとして定義してやれば完成です。</p>
<pre>
        private CustomCommand got_focus_command;

        public CustomCommand GotFocusCommand
        {
            get
            {
                if (got_focus_command == null)
                    got_focus_command = new CustomCommand(OnGotFocus, CanGotFocus);

                return got_focus_command;
            }
        }
</pre>
<p><code>CustomCommand</code> ってなんじゃい、という突っ込みが聞こえそうですが <tt>(^^;</tt>、これは<a href="https://github.com/murachi/samples-for-blog/blob/master/wpf/TimeInputSample/TimeInputSample/ViewModel/CustomCommand.cs" title="samples-for-blog/wpf/TimeInputSample/TimeInputSample/ViewModel/CustomCommand.cs at master ・ murachi/samples-for-blog ・ GitHub">自前で実装したクラス</a>です。コマンド毎に <code>ICommand</code> インタフェースを実装したクラスを定義するのは激しく面倒なので、実際の実行処理と実行可否チェックはデリゲートとして渡せばいいようにした、というものです。</p>
<p>ちなみに、フォーカスを受け取ったら全選択、みたいな処理はありふれているので、もっと再利用性の高い方法で部品化できた方がいいかもしれません。その場合は、添付 Behavior というテクニックを検討してみる価値があるかも知れません。</p>
<ul>
<li><a href="http://blogs.wankuma.com/kazuki/archive/2009/06/23/176379.aspx">[WPF][C#]テキストボックスをフォーカスがくると全選択状態にしたい - かずきのBlog</a></li>
</ul>
<p>なんかさっきから参考にしている情報のほとんどが同一人物によるものであるような気がしますが気にしないことにします <tt>(^_^;</tt> 。</p>
<h3>日時入力コントロールの実装</h3>
<p>せっかく時刻入力コントロールができたので、これに <code>DatePicker</code> を組み合わせただけのお手軽日時入力コントロールも作ってしまいましょう。</p>
<h4>XAML</h4>
<p>本当に <code>DatePicker</code> とさっきの時刻入力コントロールを並べるだけです。<a href="https://github.com/murachi/samples-for-blog/blob/master/wpf/TimeInputSample/TimeInputSample/View/DateTimeInputControl.xaml" title="samples-for-blog/wpf/TimeInputSample/TimeInputSample/View/DateTimeInputControl.xaml at master ・ murachi/samples-for-blog ・ GitHub">コード見た方が早い</a>でしょう。</p>
<h4>View Model</h4>
<p>時刻入力コントロールの部分のデータバインディングについては、時刻入力コントロール用の View Model オブジェクト <code>TimeInputControlData</code> オブジェクトをアクセサで渡すだけ渡してあげれば、あとは <code>TimeInputControlData</code> クラス内のメソッドがよしなにやってくれます。</p>
<pre>
        public TimeInputControlData Time { get; private set; }

        public DateTimeInputControlData(DateTime? dt = null)
        {
            Time = new TimeInputControlData();  // コンストラクタの中でインスタンスをぶち込むのを忘れずに…
            setDateTime(dt);
        }
</pre>
<p>プログラム側からは、日付と時刻を別々に見るのではなく、日時を 1つの <code>DateTime</code> として参照できた方が便利に決まっています。ので、それ用のアクセサ <code>DateTimeValue</code> を実装します。</p>
<pre>
        public DateTime? DateTimeValue
        {
            get { return Time.BlendWithDate(date_val); }
            set
            {
                setDateTime(value);
                NotifyPropertyChanged(&quot;Date&quot;);
                NotifyPropertyChanged(&quot;Time&quot;);
            }
        }
</pre>
<p>説明してませんでしたが、 <code>TimeInputControlData.BlendWithDate()</code> メソッドに、日付の <code>DateTime</code> に自身の時刻を混ぜ合わせた新しい <code>DateTime</code> を生成する処理を記述しています。</p>
<p>特筆すべきはそのくらいかな…?</p>
<h3>サンプルプログラム「日時メモ」</h3>
<p>せっかくなので、今回作ったコントロールを用いた簡単なサンプルプログラムを作ってみましょう。記事冒頭ですでにキャプチャ画像を示しましたが、日時と文を書いて溜めていくだけの簡単なメモ的なものです。</p>
<h4>Model - ローカルデータベース</h4>
<p>まずは Model です。単体テストを構成しやすいように別プロジェクトにしたという構成の話は冒頭ですでに記述したとおりです。</p>
<p>書き込んだメモは当然保存されることを想定しているので、保存する先としてファイルかデータベースを利用する必要があります。 .NET でもローカルデータベースは SQLight を使う方がメジャーになっているようですが (<a href="http://sqlite.phxsoftware.com/">System.Data.SQLight</a>)、一方 Visual Studio をインストールするときに一緒に入る Microsoft SQL Server にも、ローカルデータベース版の SQL Server Compact があり、追加でコンポーネントをインストールせずとも、そのままプロジェクトに組み込んで開発に利用することができます。</p>
<ul>
<li><a href="http://msdn.microsoft.com/ja-jp/library/cc645984%28v=sql.100%29.aspx">SQL Server Compact</a></li>
<li><a href="http://msdn.microsoft.com/ja-jp/library/bb686876.aspx">テクニカル リファレンス (SQL Server Compact)</a></li>
</ul>
<p>ネット上での情報が少ない (といっても必要な情報は概ね MSDN にありますが…)、<a href="http://msdn.microsoft.com/ja-jp/library/aa983326%28v=vs.100%29.aspx" title="方法 : SQL Server Compact 3.5 データベースをアプリケーションと共に配置する">配置に難がある</a>等、使い勝手の面で SQLight に劣る部分も多いですが、 .NET を使うような仕事ともなると、フリーソフトウェアを製品に組み込みづらいケースも少なくないですし ('A`)、せっかくの機会なのでこっちを使ってみることにしました。</p>
<p>ネット上にありがちな情報では、データグリッドに直接バインドしたりとか、エンティティモデルがどうのこうのとかやってたりして、単純に SQL 書いてデータ出し入れする方法がなかなか見つからなかったりするわけですが、実際のところ使い方は至って単純です。</p>
<ol>
<li>プロジェクトの参照設定に System.Data.SqlServerCe を追加する。 System.Data.SqlServerCe は .NET コンポーネントから選択できます。</li>
<li>プロジェクトへの「新しい項目」の追加で、「ローカル データベース」を選んで追加します。ここで指定したファイル名が、ローカルデータベースの DB ファイル名になります。</li>
<li>データベースエクスプローラにて、上記の DB ファイルのツリーを開き、配下の「テーブル」を右クリックして「テーブルの作成」を選びます。テーブル スキーマを編集するウィンドウが出てくるので、テーブル名やらテーブルレイアウトやらを設定します。必要になるテーブルの数だけこれを繰り返します。</li>
<li>あとは、他の DBMS を使うのと同じように DB にアクセスするコードを書いていくだけです。 connection は <a href="http://msdn.microsoft.com/ja-jp/library/system.data.sqlserverce.sqlceconnection%28v=vs.100%29.aspx"><code>System.Data.SqlServerCe.SqlCeConnection</code> クラス</a>を使います。</li>
</ol>
<p>コードの書き方は<a href="https://github.com/murachi/samples-for-blog/blob/master/wpf/TimeInputSample/TimeInputModel/NoteBook.cs" title="samples-for-blog/wpf/TimeInputSample/TimeInputModel/NoteBook.cs at master ・ murachi/samples-for-blog ・ GitHub">実際のコードを見てもらう</a>のが一番手っ取り早いと思います…。</p>
<h4>Unit Test</h4>
<p>テストコードは <a href="http://www.nunit.org/">NUnit</a> を利用したものとなっています。ここではモデルに対する単体テストはこういう形でできるんだよねという確認程度で、テスト自体は大したことはやっていません。ビルドして吐き出される DLL を NUnit の GUI ツールに読み込ませることでテストが実行でき、テスト結果とコンソール出力が見られるようです。</p>
<h3>今後の予定</h3>
<p>今回は WPF や MVVM 自体が初めてと言うことで、全工程込みで書かせていただきました。無駄にボリュームのある記事になってしまった…。</p>
<p>今後はポイントになる部分に絞った内容になっていくことになると思います。</p>
]]></content:encoded>
			<wfw:commentRss>https://blog.harapeko.jp/2013/03/01/wpf-mvvm-time-input-control/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>第5期会計報告</title>
		<link>https://blog.harapeko.jp/2012/10/28/account-5th/</link>
		<comments>https://blog.harapeko.jp/2012/10/28/account-5th/#comments</comments>
		<pubDate>Sun, 28 Oct 2012 12:37:02 +0000</pubDate>
		<dc:creator><![CDATA[村山 俊之]]></dc:creator>
				<category><![CDATA[活動記録]]></category>
		<category><![CDATA[お知らせ]]></category>
		<category><![CDATA[決算]]></category>

		<guid isPermaLink="false">http://blog.harapeko.jp/?p=264</guid>
		<description><![CDATA[第5期 (2011年9月～2012年8月年度) 会計報告 今年もこの季節がやってまいりました…。 一応、わずか [&#8230;]]]></description>
				<content:encoded><![CDATA[<p><a href="http://www.harapeko.jp/account/Statement_of_Accounts-2011_9-2012_8.pdf">第5期 (2011年9月～2012年8月年度) 会計報告</a></p>
<p>今年もこの季節がやってまいりました…。</p>
<p>一応、わずかながら、黒字ではあったようです。</p>
<p>しかし、赤字か黒字かというのは、あまり問題ではないようにも思います。大きな期待を寄せられるような事業を興している企業であれば、それだけ多くの資金を獲得することもできます。結果多くの投資を施し、大きく赤字になってその年度を終えたとしても、これはある意味で立派な企業活動であるといえます。</p>
<p>前年度の弊社の活動実態は惨憺たるもので、前々年度の赤字を受け、また喫緊で収益の見込める状況ではなかったことも踏まえて 10月以降の役員報酬支払いを止めた後は、活動資金としてわずかなお金を取引先から何とか引き出しつつ、その中で細々と経費を捻出していた、という感じでした…。それだけでは私生活までは維持できないので、かみさんに派遣で働いてもらったりもしました。</p>
<p>現在、会社の方の仕事はいったん休止し、生活費などの実資金を得るため、個人事業主としてもらった仕事をこなしている状況です。役員報酬も今期より正式に 0円に変更としました。</p>
<p>しばらくはいろんな意味で、立て直しを図る時期、ということになりそうです…。</p>
]]></content:encoded>
			<wfw:commentRss>https://blog.harapeko.jp/2012/10/28/account-5th/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
