20210507のC#に関する記事は5件です。

[.NET5 / Windows Forms] 新機能(!?) System.Windows.Forms.TaskDialog に触れてみた

前置き 今年リリースされた「.NET 5」。なんと Windows Forms に新しいコントロールが追加されていました。 本記事ではそのうちの1つ「System.Windows.Forms.TaskDialog」をご紹介したいと思います。 タスクダイアログ(TaskDialog)とは・・・ こちらの記事に詳しく書かれていますが、Vista 時点で Windows に搭載された機能のようです。 .NET Framework 時代でも Win32API を介せば使用できる機能だったようです。 Win32API での使用例はこちらのページで詳しく紹介されています。 .NET 5 で、フレームワークの標準機能として搭載されたということですね。 実例 TaskDialog のサンプルコードが公開されていたので、動作を確認してみました。 ※ 以下、掲載しているソースコードは上記のサンプルコードから引用しています 従来のMessageBox 従来のMessageBoxです。 TaskDialogでMessageBox もちろん TaskDialog でも MessageBox と同様の表現が行えます。 タスクダイアログ上のコントロールは TaskDialogPage クラスのプロパティとして設定するようです。 TaskDialogButton result = TaskDialog.ShowDialog(this, new TaskDialogPage() { Text = "Stopping the operation might leave your database in a corrupted state.", Heading = "Are you sure you want to stop?", Caption = "Confirmation (Task Dialog)", Buttons = { TaskDialogButton.Yes, TaskDialogButton.No }, Icon = TaskDialogIcon.Warning, DefaultButton = TaskDialogButton.No }); if (result == TaskDialogButton.Yes) { Console.WriteLine("User confirmed to stop the operation."); } 確認用CheckBox付きTaskDialog 「 CheckBox をONにすると、このメッセージを今後表示しない」という機能をもった、よく見かけるタイプのダイアログですね。 TaskDialogVerificationCheckBox をプロパティとして設定することで実装できます。 ダイアログ上でチェックがONになったかはpage.Verification.Checkedで取得できます。 var page = new TaskDialogPage() { Heading = "Are you sure you want to stop?", Text = "Stopping the operation might leave your database in a corrupted state.", Caption = "Confirmation (Task Dialog)", Icon = TaskDialogIcon.Warning, AllowCancel = true, Verification = new TaskDialogVerificationCheckBox() { Text = "Do not show again" }, Buttons = { TaskDialogButton.Yes, TaskDialogButton.No }, DefaultButton = TaskDialogButton.No }; var resultButton = TaskDialog.ShowDialog(this, page); if (resultButton == TaskDialogButton.Yes) { if (page.Verification.Checked) Console.WriteLine("Do not show this confirmation again."); Console.WriteLine("User confirmed to stop the operation."); } ボタンが3つあるTaskDialog これもよく見かけるタイプですね。 入力画面から遷移する際に「保存する(保存して遷移)/保存しない(保存しないで遷移)/キャンセル(画面にとどまる)」と選択肢を表示し、ユーザーに編集中の内容をどう扱うか確認させる、といった機能で見かけます。 これが MessageBox だとボタン名をカスタムできないので、表現できないんですよね。 TaskDialog であればわざわざデザイナーでダイアログを作成せずとも、表現できます。 選択肢のあるTaskDialog TaskDialogCommandLinkButton を配置することで、選択肢のあるダイアログを表現することもできます。 ボタンのTagプロパティによって、どのボタンを選択したかを判定できます。 Buttons = { new TaskDialogCommandLinkButton("&Beginner", "10 mines, 9 x 9 tile grid") { Tag = 10 }, new TaskDialogCommandLinkButton("&Intermediate", "40 mines, 16 x 16 tile grid") { Tag = 40 }, new TaskDialogCommandLinkButton("&Advanced", "99 mines, 16 x 30 tile grid") { Tag = 99 } } TaskDialogButton result = TaskDialog.ShowDialog(this, page); if (result.Tag is int resultingMines) Console.WriteLine($"Playing with {resultingMines} mines..."); else Console.WriteLine("User canceled."); } プログレスバーを設置したTaskDialog TaskDialogProgressBarを用いて、TaskDialog 上に プログレスバーを設置することも可能です。 このコードは一定時間経過後に自動で TaskDailog を閉じる実装になっています。 reconnectButton.PerformClick();により、ボタンクリックをコードで発火させることで、ダイアログを閉じることができるようです。 var page = new TaskDialogPage() { Heading = "Connection lost; reconnecting...", Text = string.Format(textFormat, (remainingTenthSeconds + 9) / 10), // Display the form's icon in the task dialog. // Note however that the task dialog will not scale the icon. Icon = new TaskDialogIcon(this.Icon), ProgressBar = new TaskDialogProgressBar() { State = TaskDialogProgressBarState.Paused }, Buttons = { reconnectButton, cancelButton } }; // Create a WinForms timer that raises the Tick event every tenth second. using (var timer = new Timer() { Enabled = true, Interval = 100 }) { timer.Tick += (s, e) => { remainingTenthSeconds--; if (remainingTenthSeconds > 0) { // Update the remaining time and progress bar. page.Text = string.Format(textFormat, (remainingTenthSeconds + 9) / 10); page.ProgressBar.Value = 100 - remainingTenthSeconds * 2; } else { // Stop the timer and click the "Reconnect" button - this will // close the dialog. timer.Enabled = false; reconnectButton.PerformClick(); } }; TaskDialogButton result = TaskDialog.ShowDialog(this, page); if (result == reconnectButton) Console.WriteLine("Reconnecting."); else Console.WriteLine("Not reconnecting."); } ページ遷移するTaskDialog 1つの TaskDialog 内で ページを切り替えることが可能です。 サンプルコードでは「処理の実行確認 → 処理実行中 → 処理完了」といったパターンの例が実装されていました。 initialPage.Navigate(inProgressPage);といった形でTaskDialogPage間で遷移させることができるようです。 // When the user clicks "Yes", navigate to the second page. initialButtonYes.Click += (sender, e) => { initialPage.Navigate(inProgressPage); }; ページ1 ページ2 ページ2の「詳細の表示」をクリックした状態 ページ3 UAC(ユーザーアカウント制御)の確認画面を表示するTaskDialog 「Restart now」をクリックすると、Windows のUAC(ユーザーアカウント制御)の確認画面が表示され、 「はい」をクリックすると TaskDialog は閉じられコマンドプロンプトが起動されます。 「いいえ」をクリックすると TaskDialog は表示されたままの状態でいます。 restartNowButton.Click += (s, e) => { restartNowButton.AllowCloseDialog = true; restartNowButton.Enabled = false; // Try to start an elevated cmd.exe. var psi = new ProcessStartInfo("cmd.exe", "/k echo Hi, this is an elevated command prompt.") { UseShellExecute = true, Verb = "runas" }; try { Process.Start(psi)?.Dispose(); } catch (Win32Exception ex) when (ex.NativeErrorCode == 1223) { // The user canceled the UAC prompt, so don't close the dialog and // re-enable the restart button. restartNowButton.AllowCloseDialog = false; restartNowButton.Enabled = true; return; } }; TaskDialog 上のコントロールのイベント補足 TaskDialog 上に RadioButton ボタンを配置することも可能です。 RadioButton ボタンのCheckChangedイベントをはじめ、配置したコントロールのイベントを補足することが可能です。 buttonNavigate.Click += (s, e) => { Console.WriteLine($"Button '{s}' Click"); // Navigate to a new page. var page2 = new TaskDialogPage() { Heading = "AfterNavigation.", Buttons = { TaskDialogButton.Close } }; page2.Created += (s, e) => Console.WriteLine("Page2 Created"); page2.Destroyed += (s, e) => Console.WriteLine("Page2 Destroyed"); page1.Navigate(page2); }; page1.Verification = new TaskDialogVerificationCheckBox("&CheckBox"); page1.Verification.CheckedChanged += (s, e) => Console.WriteLine("CheckBox CheckedChanged: " + page1.Verification.Checked); var radioButton1 = page1.RadioButtons.Add("Radi&oButton 1"); var radioButton2 = page1.RadioButtons.Add("RadioB&utton 2"); radioButton1.CheckedChanged += (s, e) => Console.WriteLine("RadioButton1 CheckedChanged: " + radioButton1.Checked); radioButton2.CheckedChanged += (s, e) => Console.WriteLine("RadioButton2 CheckedChanged: " + radioButton2.Checked); あとがき 以上、「System.Windows.Forms.TaskDialog に触れてみた」でした。 TaskDialog を使用すれば、よくある機能のパターンを簡単に実装できそうですね。 数年前、Windowsフォームの案件に従事していた時代だったら、ぜひ使ってみたかったなと思います。 しかし、これから .NET5 + Windowsフォームの案件は果たして出てるくのでしょうか・・・ 私感ですが、Windowsフォーム自体の案件も少なくなってきているのかな・・・とは思います・・・
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

C# グラフライブラリ ScottPlotのTips

C# .net 5に対応した、フリーのグラフ描画ライブラリScottPlotの使い方 覚書です。 公式サイトで、プレリリース版を推奨されているので、Pre-release版 Ver4.1系の紹介です。 開発環境 Visual Studio 2019 C# .net 5 ScottPlot Ver 4.1.13-beta 本家と解説記事 Pre-release版のインストール 描画したPlotの取得 WpfPlot1.Plot.GetPlottables() オートスケール WpfPlot1.Plot.AxisAuto(); Y2軸目に描画 var Signal = WpfPlot1.Plot.AddSignal(values); Signal.YAxisIndex = 1; 描画制限(主軸のみ) WpfPlot1.Plot.SetViewLimits(Xmin,Xmax,YMin,YMax); 描画制限(任意の追加軸) var Axis = WpfPlot1.Plot.AddAxis(ScottPlot.Renderable.Edge.Left, YAxisIndex)); Axis.Dims.SetBounds(Min, Max); サンプルWPFプログラム ソースコード MainWindows.xml <Window x:Class="ScottPlotSample1.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:ScottPlotSample1" mc:Ignorable="d" Title="MainWindow" Height="450" Width="800"> <Grid> <WpfPlot x:Name="WpfPlot1"/> </Grid> </Window> MainWindows.xml.cs using ScottPlot; namespace ScottPlotSample1 { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); double[] values1 = DataGen.RandomWalk(100_000); double[] values2 = DataGen.RandomWalk(10_000); double[] values3 = DataGen.RandomWalk(1_000); WpfPlot1.Plot.AddSignal(values1, sampleRate: 1000); WpfPlot1.Plot.AddSignal(values2, sampleRate: 100); WpfPlot1.Plot.AddSignal(values3, sampleRate: 10); //描画されているSignalPlotをリスト化 var Signals = GetPlotableList<ScottPlot.Plottable.SignalPlot>(WpfPlot1); //現在のY軸をリスト化 var YAxes = WpfPlot1.Plot.GetSettings().Axes.Where(x => x.IsVertical == true).ToList(); //足りないY軸を追加 for (int YAxisIndex = YAxes.Count; YAxisIndex < Signals.Count; YAxisIndex++) //軸インデックスがない場合は追加する { YAxes.Add(WpfPlot1.Plot.AddAxis(ScottPlot.Renderable.Edge.Left, YAxisIndex)); } //各軸に描画 for (int No = 0; No < Signals.Count; No++) { Signals[No].YAxisIndex = No; } //オートスケール WpfPlot1.Plot.AxisAuto(); //X軸を表示制限 var AxisLimits = WpfPlot1.Plot.GetAxisLimits(); WpfPlot1.Plot.SetViewLimits(AxisLimits.XMin, AxisLimits.XMax); //各Y軸の設定(色指定、ラベル、表示制限) for(int No = 0; No <YAxes.Count; No++) { YAxes[No].Ticks(true); YAxes[No].Color(Signals[No].Color); YAxes[No].Label($"Signal{No}"); AxisLimits = WpfPlot1.Plot.GetAxisLimits(yAxisIndex: YAxes[No].AxisIndex); YAxes[No].Dims.SetBounds(AxisLimits.YMin, AxisLimits.YMax); } } /// <summary> /// WpfPlotの中にあるすべてのTのリストを返す /// </summary> /// <typeparam name="T">ScottPlot.Plottable Type</typeparam> /// <param name="fp"> WpfPlot</param> /// <returns></returns> private List<T> GetPlotableList<T>(WpfPlot fp) { List<T> Plotables = new List<T>(); var AllPlottables = fp.Plot.GetPlottables(); foreach (var Plottable in AllPlottables) { switch (Plottable) { case T Plotable: Plotables.Add(Plotable); break; } } return Plotables; } } }
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

C# PowerPointをHTMLに変換

今日はC#についての話です。そして、Spire.Presentationという無料のライブラリを使って、PowerPointをHTMLに変換する方法を紹介します。 下準備 1.E-iceblueの公式サイトからFree Spire. Presentation無料版をダウンロードしてください。 2.Visual Studioを起動して新規プロジェクトを作成してから、インストールされたファイルにあった相応しいSpire. Presentation.dllを参照に追加してください。 (Net 4.0を例としたら、デフォルトパスは“Bin→NET4.0→Presentation.dll”というようになります。) 元のファイル using Spire.Presentation; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { //PowePoint Objectを作成します。 Presentation ppt = new Presentation(); //ファイルをロードします。 ppt.LoadFromFile(@"Sample.pptx"); //HTMLで保存します。 ppt.SaveToFile("ConvertPPTtoHtml.html", FileFormat.Html); } } } 実行結果  
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Ubuntu Gtkアプリ イベントハンドラー編

Ubuntu Gtkアプリ イベントハンドラー編 コード上でイベントハンドラーを書くパターン 従来通りイベントハンドラーとコールバック関数を書くやり方 Riderのエディタの場合関数のコードヒントが効きます。 namespace event2GtkApplication { class MainWindow : Window { [UI] private Button _button1 = null; public MainWindow() : this(new Builder("MainWindow.glade")) { } private MainWindow(Builder builder) : base(builder.GetRawOwnedObject("MainWindow")) { builder.Autoconnect(this); _button1.Clicked += Button1_Clicked; } private void Button1_Clicked(object sender, EventArgs a) { Console.WriteLine(e); } } } 課題 すべてのコントロールにイベントハンドラーとコールバック関数を書かないといけない。 コールバック関数の引数がわからないことがある。 Windows版のVisalStudioはボタンを押すとイベントハンドラーとコールバック関数を自動生成してくれて便利な機能があった Gladeにコールバック関数名を書くやり方 Gladeにコールバック関数名を書きコードにコールバック関数を書きます。 イベントハンドラーはAutoConnectで裏で処理してくれてる using System; using Gtk; using UI = Gtk.Builder.ObjectAttribute; namespace EventGtkApplication { partial class MainWindow : Window { [UI] private Button btn2 = null; public MainWindow() : this(new Builder("MainWindow.glade")) { } private MainWindow(Builder builder) : base(builder.GetRawOwnedObject("MainWindow")) { builder.Autoconnect(this); } public void on_btn2_clicked(Object sender,EventArgs e) { Console.WriteLine("" + sender); Console.WriteLine("" + e); } } } イベントーハンドラーの記入は不要 btn2.Clicked += on_btn2_clicked; 以下の状態だとビルドができない Glade上にコールバック関数名を記入。コード上にコールバック関数がない Glade上にコールバック関数名を記入。コード上のコールバック関数の名前が一致しない 以下の状態だとビルドができる Glade上に2つのボタンに同じコールバック関数を名記入。コード上のコールバック関数が同じ(非推奨) 課題 コールバック関数も自動生成したい。 WindowsやMonoDevelopでは自動生成があり便利だった。 GTK3はリリースしてから10年以上経つ。流石に自動生成するオープンソースがあるはず Gladeからコールバック関数を自動生成するものを探す gitに上がっているGladeToCppが理想に違いが自動生成されるコードはC++であり対象外 あとはpythonでpythonのGTKを生成するものが少々 glade gtk python generatorで検索するとヒットします。 C#を書き出してくるものがあまり見当たらない 続く
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Gtk3アプリ イベントハンドラー編

Gtk3アプリ イベントハンドラー編 コード上でイベントハンドラーを書くパターン 従来通りイベントハンドラーとコールバック関数を書くやり方 Riderのエディタの場合関数のコードヒントが効きます。 namespace event2GtkApplication { class MainWindow : Window { [UI] private Button _button1 = null; public MainWindow() : this(new Builder("MainWindow.glade")) { } private MainWindow(Builder builder) : base(builder.GetRawOwnedObject("MainWindow")) { builder.Autoconnect(this); _button1.Clicked += Button1_Clicked; } private void Button1_Clicked(object sender, EventArgs a) { Console.WriteLine(e); } } } 課題 すべてのコントロールにイベントハンドラーとコールバック関数を書かないといけない。 コールバック関数の引数がわからないことがある。 Windows版のVisalStudioはボタンを押すとイベントハンドラーとコールバック関数を自動生成してくれて便利な機能があった Gladeにコールバック関数名を書くやり方 Gladeにコールバック関数名を書きコードにコールバック関数を書きます。 イベントハンドラーはAutoConnectで裏で処理してくれてる using System; using Gtk; using UI = Gtk.Builder.ObjectAttribute; namespace EventGtkApplication { partial class MainWindow : Window { [UI] private Button btn2 = null; public MainWindow() : this(new Builder("MainWindow.glade")) { } private MainWindow(Builder builder) : base(builder.GetRawOwnedObject("MainWindow")) { builder.Autoconnect(this); } public void on_btn2_clicked(Object sender,EventArgs e) { Console.WriteLine("" + sender); Console.WriteLine("" + e); } } } イベントーハンドラーの記入は不要 btn2.Clicked += on_btn2_clicked; 以下の状態だとビルドができない Glade上にコールバック関数名を記入。コード上にコールバック関数がない Glade上にコールバック関数名を記入。コード上のコールバック関数の名前が一致しない 以下の状態だとビルドができる Glade上に2つのボタンに同じコールバック関数を名記入。コード上のコールバック関数が同じ(非推奨) 課題 コールバック関数も自動生成したい。 Windows VisualStudioやMonoDevelopでは自動生成があり便利だった。 GTK3はリリースしてから10年以上経つ。流石に自動生成するオープンソースがあるはず Gladeからコールバック関数を自動生成するものを探す gitに上がっているGladeToCppが理想に違いが自動生成されるコードはC++であり対象外 あとはpythonでpythonのGTKを生成するものが少々 glade gtk python generatorで検索するとヒットします。 C#を書き出してくるものがあまり見当たらない 続く
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む