trapemiyaの日記

hatenablogが新しくなったんで新規一転また2019年1月からちょこちょこ書いてます。C#中心のプログラミングに関するお話です。

サンプルコードをアップしました。「【WPF】 ComboBoxにEnumをバインドする」

コードとしてはネットを探せば見つかりにくいものではありませんが、日本語としてまとまっているものは少ないと思いましたので、サンプルとしてアップしました。

WPF】 ComboBoxにEnumをバインドする
https://code.msdn.microsoft.com/WPF-ComboBoxEnum-ddd26709

きっかけは以下のページです。

Comboboxの値の保存と表示について
https://social.msdn.microsoft.com/Forums/ja-JP/7d529f6e-41f4-41fb-9f4c-5aeaa1cef403/combobox?forum=csharpgeneralja

「構成システムを初期化できませんでした」とエラーが出てアプリが起動しなくなった。

Visual Studio 2015で開発中に、「構成システムを初期化できませんでした」とエラーが出て、アプリケーションが実行できなくなった。
しばし悩んだが、エラーの詳細を確認すると、以下の記述があることを発見。

InnerException:
BareMessage=認識されない構成セクション userSettings です。
Filename=C:\Users\[ユーザー名]\AppData\Local\[アプリ名]\[アプリ名].vshost.exe_Url_3d3aml51muxarmeim3nzzgqmoa1if2a3\1.0.0.0\user.config
HResult=-2146232062
Line=3
Message=認識されない構成セクション userSettings です。 (C:\Users\[ユーザー名]\AppData\Local\[アプリ名]\[アプリ名].vshost.exe_Url_3d3aml51muxarmeim3nzzgqmoa1if2a3\1.0.0.0\user.config line 3)
Source=System.Configuration

上記のuser.configファイルに、Visual Studioのプロジェクトのプロパティの設定から、さっき消したはずのユーザー定義の変数が残っていた。今回、user.configにはこの変数しか無かったので、user.configファイルを削除して無事に動作するようになった。それにしてもどうして残っちゃったんだろうね?

Windows 10 の全体像と社内展開を無料で学べる IT 技術者向けオンライン講座 10/14 開催

世界中の Microsoft MVP が IT 技術者にお送りする、「Windows 10 の全体像と社内への展開方法」をテーマとしたオンライン講座「Windows 10 IT Pro Readiness」が開催されます。日本では 10 月 14 日(水)20 時より Microsoft MVP for System Center Cloud and Datacenter Management の杵島正和さんと後藤諭史さんが登壇され、主に下記のトピックについてライブ Q&A 形式でセッションが開催されます。

この講座に参加するためには事前登録が必要であり、この講座のURLを取得する際に30分程度時間が必要となる場合があるようですから、参加される方は以下より早めにご登録ください。Windows 10について理解を深める絶好のチャンスですね!

Windows 10 IT Pro Readiness - Powered by MVPs (Japan)
https://mvp.eventbuilder.com/event?eventid=x2z6f8

 IIS 8.5上で実行しているCrystal Reportsにデータが表示されない

Windows Server 2003 から、Windows Server 2012 R2 へASP.NETアプリケーションの移行テストを行っています。
その際、クリスタルレポートにデータが全く表示されないという現象が発生しました。
クリスタルレポートに渡したパラメーターは問題なく印刷されています。問題となるのはどうやらデータバインドしている部分のようです。
具体的には、DataGridにバインドしているDataSetのデータが一件も印刷されません。表の部分がブランクになってしまうのです。
結構、悩みましたが、答えはネット上にありました。

unable to load crystal report in windows server 2012
http://stackoverflow.com/questions/15744771/unable-to-load-crystal-report-in-windows-server-2012

どうやら、IIS 8では、クリスタルレポートのランタイムのバージョンが、13.0.6以上である必要があるようです。
私がテストしているOSはWindows Server 2012 R2で、IIS 8.5ですので、以下より最新版のラインタイムを落として入れ替えてみました。

SAP Crystal Reports, developer version for Microsoft Visual Studio: Updates & Runtime Downloads
http://scn.sap.com/docs/DOC-7824?rid=/webcontent/uuid/d01fdad8-44e5-2d10-61ad-9d2d4158f3a8

と、あっさり動いてしまいました。助かりました。

Windows Updateの結果、「Windows 更新プログラムの構成中」のまま終わらずログオン画面が表示されない

表記の状態になるコンピューターが社内で感覚的に2割程度発生しました。今のところ、いずれもWindows 7 64bit Professional SP1 ですが、この環境でも正常に起動するコンピューターの方が圧倒的に多い状況です。
いずれも、CTRL + ALT + DEL で、普通にログオン画面が表示され、通常通り使用できているようです。
古くは以下のサポート情報がありますが、同じようなことなのかもしれません。

KB2533552 の修正プログラムと他の更新プログラムを同時に適用すると、再起動時に "Windows を構成するための準備中" と表示されたままログオン画面に切り替わらない場合がある
https://support.microsoft.com/ja-jp/kb/2618153

そういうわけでドタバタする一日の始まりでした。

Windows Server 2012 R2に対してVisual StudioからWeb発行するための設定

今更感がありますが、半日潰したのでメモしておきます。

では、標記の通り、Visual StudioASP.NETプロジェクトを、Windows Server 2012 R2に対してWeb発行できるようにするための、Windows Server 2012 R2の設定を以下に示します。

1.サーバーマネージャーの「役割と機能の追加ウィザード」からIISを追加する。
また、そのウィザードの途中で「管理ツール」にある「管理サービス」にもチェックを入れること。これが、Web Management Serviceに当たる。これは、Visual StudioからWeb発行する際に必要となるものの一つ。
インストール後、サービスにWeb Management Serviceが追加される。こいつは自動で起動しないので、自動で起動するように変更し、起動させておく。

また、Web配置も必要なので、以下のようにインストールする。

Microsoft Web Platform Installer 5.0
http://www.microsoft.com/web/downloads/platform.aspx

を開き、右にある「Free Download」のボタンを押し、実行する。
Web Platform Installer 5.0が起動する。
・「製品」カテゴリーをクリックする。
・「Web Deploy 3.5」を追加ボタンを押して追加する。
インストールが完了すると、Web Deployment Agent Serviceというサービスが追加され、自動的に起動している。

以上でWeb発行ができるようになる。

わかってしまえば大した手順ではないのですが、それなりに悩みました。

ViewModelからViewのメソッドを実行する。

音声ファイルを再生する。
http://d.hatena.ne.jp/trapemiya/20150330/1427700162

の続きです。遅くなりすみません。

さて、音声ファイルの再生方法は、androidiOS等、各プラットフォームによって異なります。よって、この音声を再生する記述は、各プラットフォーム毎のクラスに書いた方が、PCLで各プラットフォーム毎に場合分けして書くよりもスマートです。そうすると、PCL、つまりViewModelから各プラットフォームのクラスに対して、音声再生処理のお願いをしなければなりません。MVVMにおいてこの問題は良く出てくる話です。私も、WPFの開発をMVVMで始めた際にいろいろと悩みました。
ViewModelはViewのインスタンスとは疎結合ですから、ViewModelからViewに対して何らかの手動で連絡を取る必要があります。その手段として、ここではMessenger Pluginを使用します。プラグインはMvvmCrossに用意されている機能であり、IoCコンテナを利用して実現されています。

では、早速、Messenger Pluginを導入しましょう。

ソリューションエクスプローラーでPCLプロジェクトの「参照設定」を右クリックし、「NuGetパッケージの管理」をクリックします。そして、以下の図ように「Messenger Plugin」をインストールして下さい。

同様のことをandroid等、各プラットフォームのプロジェクトでも行って下さい。ここではandroid用プロジェクトのみを扱うものとします。

Messenger Pluginは、以下のようにMvx.ResolveメソッドでMvxMessengerHubオブジェクトを注入し、そのオブジェクトのPublishメソッドでメッセージを送ります。

var messenger = Mvx.Resolve<IMvxMessenger>();
messenger.Publish(new 汎用Message(this, "Play!"));

上記のメソッドが記述されているViewModel、および、メッセージオブジェクトである汎用Messageクラスの全容を以下に示します。

public class FirstViewModel
    : MvxViewModel
{
    /// <summary>
    /// コンストラクタ
    /// </summary>
    public FirstViewModel()
    {
        PlayCommand = new MvxCommand(Play);
    }
    
    private string _hello = "Hello MvvmCross";
    public string Hello
    {
        get { return _hello; }
        set { _hello = value; RaisePropertyChanged(() => Hello); }
    }

    public MvxCommand PlayCommand { get; private set; }

    private void Play()
    {
        var messenger = Mvx.Resolve<IMvxMessenger>();
        messenger.Publish(new 汎用Message(this, "Play!"));
    }
}

public class 汎用Message : MvxMessage
{
    public 汎用Message(object sender, object param) : base(sender) { this.Param = param; }

    public object Param { get; set; }
}

メッセージを受け取る側、つまりViewでは以下のようにして、メッセージが来るのを待ちます。

var messenger = Mvx.Resolve<IMvxMessenger>();
MvxSubscriptionToken _tokenEnd = messenger.SubscribeOnMainThread<汎用Message>(OnReceiveMessage);

メッセージが来たらOnReceiveMessageメソッドが実行され、そこで音楽が再生されます。
上記のメソッドが記述されているViewのコードの全容を以下に示します。

public class FirstView : MvxActivity
{
    protected override void OnCreate(Bundle bundle)
    {
        base.OnCreate(bundle);
        SetContentView(Resource.Layout.FirstView);

        //起動時に音楽を鳴らすのを止める。
        //MediaPlayer.Create(this, Resource.Raw.c9).Start();

        var messenger = Mvx.Resolve<IMvxMessenger>();
        MvxSubscriptionToken _tokenEnd = messenger.SubscribeOnMainThread<汎用Message>(OnReceiveMessage);
    }

    public void OnReceiveMessage(汎用Message message)
    {
        if (message.Sender != ViewModel)
            return;

        MediaPlayer.Create(this, Resource.Raw.c9).Start();
    }
}

Messenger Pluginは、IoCコンテナの特徴の一つであるsingletonオブジェクトを介して、メッセージを伝達しています。Messenger Pluginがなぜsingletonになるかは、以下のソースコードの通り、Mvx.RegisterSingletonメソッドで登録されているからです。

MvvmCross/Plugins/Cirrious/Messenger/Cirrious.MvvmCross.Plugins.Messenger/PluginLoader.cs
https://github.com/MvvmCross/MvvmCross/blob/c306ba37afd9024f68b7a4f1fedcaf4cf7d01b8d/Plugins/Cirrious/Messenger/Cirrious.MvvmCross.Plugins.Messenger/PluginLoader.cs#L27

以上、おつかれさまでした。

(参考としたページ)
Executing UI Code from ViewModel on MVVMCross
http://stackoverflow.com/questions/15590776/executing-ui-code-from-viewmodel-on-mvvmcross