WPFでデスクトップマスコット作る

3年前ぐらいに、WPFについて記事を書いていました。

この時に、何か作りたい的なことを言っていたので、デスクトップマスコットを作ろうと思いました。


デスクトップマスコットを作る

C#/WPFで作るデスクトップマスコット入門を参考に作成しました。
・背景を透明化してイラストをデスクトップに表示する

・クリックしてドラッグすると動かせる

イラストは山口(はる)ちゃんが描いてくれました

※本当ははるちゃんと協力して、このイラストをLive2Dで動かすブログを作成するつもりでしたが難しかったので止めました(暴)

 

ここから少しだけ改良を加えてみます。

 

①サンタさんの挨拶

コンテキストメニューで「挨拶」をクリックすると、ランダムに3種類の挨拶をするウィンドウを表示します。

ウィンドウの表示位置は、デスクトップマスコットを表示している位置から相対的に設定しています。(マスコットの初期位置は画面右下に設定)

 

詰まった点:ウィンドウを一度閉じた後、再度表示しようとするとエラーが発生する。

'System.InvalidOperationException: 'Window が閉じた後で、Visibility の設定や、Show、ShowDialog、および WindowInteropHelper.EnsureHandle の呼び出しを行うことはできません。'

⇒ググると、ウィンドウを閉じるのではなく、非表示にするという解決方法がメジャーのようです。そのため、閉じるイベントをキャンセルし、非表示にすするという処理を追加します。が、それだけだと、永遠にデバッグが終わらなくなりました。

以下のように、アクティブの時のみ閉じるイベントをキャンセルし、非表示にすることで回避できました。

private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
    if ((sender as MessageWindow).IsActive)
    {
        e.Cancel = true;
        this.Visibility = Visibility.Hidden;
    }
}

②AngleShapeを使ってWeb情報を取得する

コンテキストメニューで「天気」をクリックすると、天気サイトから、京都市下京区の今日の天気と明日の天気を取得してウィンドウに表示します。

AngleShapeを使って、情報を取得しました。

※本当はコロナ情報を取得して表示しようと思ってましたがいろいろ大変だったのでやめました

 

AngleShapeとは?

C#で利用できるhtmlパーサーです。

C#開発環境で、Javascriptで広く利用されているDOM (Document Object Model)を使用して、Webページの内容を取得します。

以下サイトがかなり参考になります。

C#で利用できるhtmlパーサーAngleSharpを使用する

 

・読み込み

StreamReaderに読み込んだ後に、parser.ParseDocumentで変換します。

var urlstring = "https://tenki.jp/forecast/6/29/6110/26106/";
var req = (HttpWebRequest)WebRequest.Create(urlstring);
using (var res = (HttpWebResponse)req.GetResponse())
using (var stream = res.GetResponseStream())
using (var sr = new StreamReader(stream))
{
    var text = sr.ReadToEnd();
    var parser = new HtmlParser();
    doc = parser.ParseDocument(text);
}

・取得

doc.QuerySelectorAll("section[class=today-weather] div[class=weather-icon]")のような形で、セレクタを指定すると、対象のhtmlElementが取得できます。

セレクタはブラウザの開発ツール(F12)から、取得したい箇所を探します。

今回は、今日と明日の天気のアイコン、最高気温、最低気温を取得しました。

ダウンロード
DeskTopMascot.zip
zip ( 圧縮 ) ファイル 12.9 MB

今の業務でtypescriptやhtmlを使用するため、以前記事を書いていた時にはよくわからなかったことがわかるようになっていて、成長を感じました。

次もWPFで何か作るか、Unityでゲーム作るか、諦めたLive2Dに再挑戦するかしたいと思います。