スイッチボットは、家庭の照明スイッチに貼り付けて、スマートホーム化に使用されるIoTデバイスです。
一般的にはリモコン操作や遠隔操作で照明や家電を制御できるようになります。
最近の案件で、工場の既存の生産設備にスイッチボットを取り付けて、遠隔操作を行う案件を行いました。
スイッチボット自体は低価格で手軽に導入でき、ソフト開発の費用も最初の1台分だけなので、複数台の既存設備に簡単安価にレトロフィットすることが可能です。
先日、iPhoneアプリのGUIを「ASP.NET Core MVC」に置き換える仕事を行いました。
今まで苦手であったWEB(HTML+CSS)の開発が人並みには出来るようになったと思います。
最近は工場向けの案件でもスマホでIoT見える化を行い、設備の稼働状態表示やエラー通知を行うなどのニーズなどがあるので、弊社のような制御系ソフト会社でもWEBアプリの知識が必要になってきています。
いくつか今後の開発のためにメモを残しておこうと思います。
今までWEBでのUI要素の配置が思うようにいかず、デスクトップアプリより柔軟性がないと思っていましたが、flexを使用するとほぼデスクトップアプリと同じ間隔で配置できるようになりました。
まずはflexを使用し、うまくいかない場合だけ他の方法を使用するのがよさそうです。
クライアントからサブミットしてサーバに一旦戻して再描画するとスクロール位置が上に戻ってしまいます。
これはサブミット前にスクロール位置をinputタグに格納し、再描画時に同じスクロール位置に戻せば解決します。
これを各ページで行うのではなく、全てのページで共通実装にするのが良いです。
アイコンライブラリを使用して簡単にアイコンが表示できます。
https://icons.getbootstrap.jp/
以下のBootstrapの目次を見た感じだと、スピナー、トースト、ツールチップあたりは導入しやすくすぐに役立ちそうです。
https://bootstrap-guide.com/outline
WEBからダウンロードしたファイルはセキュリティブロックされており、「Microsoft Defender SmartScreen」の確認画面が表示されたりします。
このセキュリティブロックを解除するには、代替データストリームのZone.Identifierを削除する必要があります。
C#で解除する拡張メソッドを作成しました。
以下のUnblockメソッドを実行すると解除できます。
[DllImport("kernel32", CharSet = CharSet.Unicode, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool DeleteFile(string name);
public static void Unblock(this FileInfo file) {
file.IsReadOnly = false;
DeleteFile(file.FullName + ":Zone.Identifier");
}
業務で久しぶりにVSTOを使用しました。
VSTOは、EXCELやWordなどのOfficeアプリケーションをカスタマイズし、機能を拡張するためのフレームワークです。これは、EXCELマクロ(VBA)の代替として使用され、以下の点で優れています。
1. C#で実装:VSTOはレガシーなVBではなく、C#でアプリケーションを拡張できます。
2. .NETのフル機能:VSTOは.NETフレームワークの全機能を利用できます。
3. GUI:WindowsFormsやWPFを使用して、Officeアプリケーションのユーザーインターフェースをカスタマイズできます。
4. コードの隠蔽:VSTOを使用することで、コードを隠蔽してアプリケーションを保護できます。
お客様がEXCELのVBAを使用して、工場内の設備の出来高や計測結果の集計などをされている場合がよくあります。
このようなVBAマクロをVSTOに置き換えることは、ユーザにとって新たな価値が生まれる可能性があります。
今後もVSTOを使用して効率的な開発を進めていきます。
今回は弊社で開発しているアプリに実装したAIチャット機能についてご紹介します。
この機能は、アプリをさらにユーザフレンドリーにし、質問応答をスムーズに行えるようにするために導入されました。
「Azure OpenAI」と「Azure AI Search」を組み合わせて、AIチャット機能を実現しました。以下に、具体的な手順を説明します。
実際にこのAIチャット機能を試してみると、以下のような驚くべき効果がありました。
AIチャット機能は、技術アピールにもなりつつ、ユーザフレンドリーなアプリを作成するための非常に有効な手段であると感じています。今後もAI技術を駆使して、さらなるユーザビリティ向上を行っていきます。
今回は、C#でダブルバッファを使って画面のちらつきを防ぐ方法についてです。
画面がちらつくという現象は、画面の描画が速く行われるときに起こります。例えばウィンドウをリサイズしたりすると、画面の一部が更新されます。
このとき画面の更新が一瞬で行われると、画面がちらついて見えることがあります。これは、画面の更新がユーザーの目に追いつかないために起こります。
画面のちらつきを防ぐには、ダブルバッファという技術を使います。
ダブルバッファとは、画面に表示するデータを2つのバッファに分けて管理する方法です。
一つのバッファは、画面に表示されるバッファで、もう一つのバッファは、画面に表示する準備をするバッファです。
画面の更新が必要になったときには、準備されたバッファを画面に表示するバッファと入れ替えます。
このようにすると、画面の更新が一瞬で行われるのではなく、スムーズに行われるので、画面のちらつきが防げます。
C#のWindowsFormsでダブルバッファを使うには、DoubleBufferedプロパティを使用します。
DoubleBufferedプロパティは、コントロールのダブルバッファを有効にするかどうかを表すプロパティです。
DoubleBufferedプロパティをtrueにすると、コントロールのダブルバッファが有効になります。
ただし、単に自身のコントロールのDoubleBufferedをtrueにするだけでは、子コントロールのちらつきは防げません。
子コントロールも含めて全てのコントロールのDoubleBufferedをtrueにする必要があります。
しかし、子コントロールのDoubleBufferedは、通常は外部から設定できません。
そこで、リフレクションを使って、外部から子コントロールのDoubleBufferedを設定できるようにし、子コントロールのDoubleBufferedプロパティを再帰的にtrueに設定します。
このようにして、C#でダブルバッファを使って画面のちらつきを防ぐことができます。
C#のStopwatchクラスを使用する際によくあるパターンとして、あるフラグによってスタートまたはリセットしたり、リスタートまたはリセットしたりする場合があります。
せっかくなので拡張メソッドを作成してみました。
実装はしょうもない内容ですが、これによりコードがスッキリします。
public static void StartOrReset(this Stopwatch sw, bool start) { if (start) { sw.Start(); } else { sw.Reset(); } }
public static void RestartOrReset(this Stopwatch sw, bool restart) { if (restart) { sw.Restart(); } else { sw.Reset(); } }
DataGridViewの列幅オートサイズモード(AutoSizeColumnsMode)がAllCellsなどのようにセルの内容によってオートサイズするモードの場合、セルのValueの設定回数が多いと描画が遅くなります。
これを改善するために、列幅オートサイズモードを一旦Noneに変更する拡張メソッドを作成しました。
これにより劇的に速度改善しました。
/// <summary>処理実行中に列幅のオートサイズを停止します。セルのValueの設定回数が多い場合、オートサイズ処理が遅いため、一旦オートサイズを停止することで高速化を行います。</summary> public static void SuspendColumnAutoSize(this DataGridView dgv, System.Action action) { //注意:AutoSizeRowsModeは対象外。Noneに変更しただけで遅いため //finallyで行う処理 System.Action finallyAction = () => { }; //AutoSizeColumnsModeがNoneなどでない場合はNoneに変更する if (dgv.AutoSizeColumnsMode.EqualsAny(DataGridViewAutoSizeColumnsMode.None, DataGridViewAutoSizeColumnsMode.Fill).Not()) { var mode = dgv.AutoSizeColumnsMode; finallyAction += () => dgv.AutoSizeColumnsMode = mode; dgv.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.None; } //列のAutoSizeColumnsModeがNoneなどでない場合はNoneに変更する foreach (var col in dgv.Columns.ToList()) { if (col.AutoSizeMode.EqualsAny(DataGridViewAutoSizeColumnMode.None, DataGridViewAutoSizeColumnMode.NotSet, DataGridViewAutoSizeColumnMode.Fill).Not()) { var mode = col.AutoSizeMode; finallyAction += () => col.AutoSizeMode = mode; col.AutoSizeMode = DataGridViewAutoSizeColumnMode.None; } } //処理実行 try { action(); } finally { finallyAction(); } }
UAC(ユーザアカウント制御)や、「UACによる管理者昇格時の同意プロンプト表示」の有効/無効によって処理を変えたい場合があったので取得方法を調べました。
結果、レジストリを調べれば良いことが分かりました。簡単ですね。
以下のプロパティを実装してみました。
/// <summary>UAC(ユーザアカウント制御)が有効か</summary> public static bool? IsUacEnabled { get { try { var key = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System"); if (key == null) return null; var value = key.GetValue("EnableLUA"); if (value == null) return null; return value.Equals(1); } catch { return null; } } } /// <summary>UACによる管理者昇格時の同意プロンプト表示が有効か</summary> public static bool? IsAdminConsentPromptEnabled { get { try { var key = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System"); if (key == null) return null; var value = key.GetValue("ConsentPromptBehaviorAdmin"); if (value == null) return null; return value.Equals(0).Not(); } catch { return null; } } }