ファイルの変更をRxで監視する
前人の知恵がググると簡単にでてきます
まぁこれでホボ完成なんですが私はコンソールアプリで読み込むだけだったので、スケジューラー指定してとかそういうところを割愛
するとファイルの変更イベントが2回上がるようになりました
ほぼ同時なので2回目のイベントでのファイル読み込みは1回目の読み込みの影響でだいたい失敗します
これまたググると
メモ帳の場合ファイルの保存で1回、属性の変更で1回ファイルを更新するよ、そしてこの動作は他のアプリでも同じだよ、的なことが書いてあるような気がします
今回は変更があったらファイルを読むとかその程度の動きができればいいのでThrottleで2回連続を1回にまとめました
private FileSystemWatcher _watcher; private IDisposable _disposable; public FileWatcher(string fileName) { var file = new FileInfo(fileName); _watcher = new FileSystemWatcher(); _watcher.Path = file.Directory?.FullName; _watcher.Filter = file.Name; _watcher.NotifyFilter = NotifyFilters.LastWrite; _disposable = Observable.FromEventPattern<FileSystemEventHandler, FileSystemEventArgs>( h => this._watcher.Changed += h, h => this._watcher.Changed -= h) .Throttle(TimeSpan.FromSeconds(.1)) .Subscribe(e => this.ReadFile(e.EventArgs.FullPath)); _watcher.EnableRaisingEvents = true; } public void Stop() { _disposable?.Dispose(); _watcher?.Dispose(); } private void ReadFile(string file) { try { using (var stream = new FileStream(file, FileMode.Open, FileAccess.Read)) { } } catch (Exception exp) { System.Diagnostics.Debug.WriteLine("read error."); } }
まぁ100msも待てば十分でしょう
Microsoft.Maps.MapControl.WPF の残念なうごき
Microsoft.Maps.MapControl.WPFはNuGetで入れることができるWPF用の地図コントロールです
ベースとなる地図がBing MapsになっているだけのよくあるTMS(?)のコントロールで最新版は1.0.0.3(2015/02/19)となっています
このコントロールはMapCore.BoundingRectangle
プロパティを参照することで現在表示している領域の東西南北が取得できます
ということで地図が移動した時の西と東の度を画面上に表示するだけのアプリを作ってみました(わかると思いますが西を左側、東を右側にだしてます)
東が180°を超えた瞬間に西と東が入れ替わります
BoundingRectangleプロパティが返すLocationRect
クラスがWestとEastをイイ感じ(?)に入れ替えてくれるのが原因なんですが、どう見てもバグです、すごく困ります
LocationRectクラスはどうやら
- West < East
- 緯度は±180の中にある
を保証しようとしているためにこんなことになっているようです (これだと経度180度線が入った領域は表現できませんよね)
Microsoft.Maps.MapControl.WPFの中ではLocationRectを使う箇所がいくつかあるんですが、上の値チェックはクラスに側が保証していることを前提にできていたりするので、ちょっと修正とかできないんだろうなーとは思うんですがどうなんでしょう
そもそもバグ報告をどこにしていいのかも分からないし、とっくにサポートおわってんじゃないかとか思っていたり
ちなみにUWP版にはこのプロパティはありません
.Net Framework 4.7 のWPF Touch/Stylus support をあまり考えずに有効にしたらはまったこと
早いもので半年以上前にリリースされた.Net 4.7です
リリースノートはこちら
この記事に
WPF Touch/Stylus support for Windows 10
ってのがありまして、More reliableとかMore capableとかよさげなことが書いてあるんですね
ということで何も考えずに有効にしてました
有効にするにはapp.configに
<configuration> <runtime> <AppContextSwitchOverrides value="Switch.System.Windows.Input.Stylus.EnablePointerSupport=true"/> </runtime> </configuration>
って足せばいいだけなので簡単ですね
問題発生
とりあえず下に動画貼ります(iPhoneで撮った動画をそのまま上げたらなんか小さいんですがなんでですか)
Surface Pro2現役ですよ!!!1
WPFでInkCanvasを置いて画面左上のボタンでデスクトップを180°回転できるようにしてます
デスクトップの回転はUser32.dll
のSetDisplayConfig
を呼んでます
通常時は当たり前ですがちゃんとペンでなぞった部分に描画します
しかし180°回転させた状態でペンで描くと180°反対側に描画してしまいます(動画には入っていませんがマウスだとちゃんとポインターの場所に描画されます)
dnSpyさんで処理を追っていくとStylusのMoveイベントの時の座標取得をStylus系(?)じゃなくてPointer系(マウスの座標とるやつ)を使っていてそれが画面の回転を考慮してないっぽいんですね
上で追加した設定でもうちょっとググったら
軽減策: ポインター ベースのタッチおよびスタイラスのサポート | Microsoft Docs
なんてのが
WM_POINTERベースにするってかいてあるんですが、そんなことリリースノートに書いてないと思うんですよ
ということで先ほどの設定を消して実行すると
デスクトップを回転してもちゃんとStylusの位置に描画されました
この動作が仕様通りなのかバグなのかもわからないし、あの設定はなんのためにできたんだろう(しらべてない)
きっとだれの参考にもならないことでした