Quantcast
Channel: C#タグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 9707

Windows GUIプログラミング入門27 ヘルプ画面

$
0
0

■はじめに

今回は画面内にヘルプページを表示するサンプルと、画面パーツを別xamlにするやり方を学びます。
これらの実装例として、正規表現の動作確認ツールを作ります。
000.png

■開発環境

  • Windows 10
  • Visual Studio Community 2019 (Version 16.8.2)
  • .NET Framework 4.6.2 / .NET Core 3.1 / .NET 5.0

■プロジェクト作成

RegexTesterという名前でプロジェクトを作成します。

◇.NET Frameworkの場合

001.png

002.png

◇.NET Core 3.1 / .NET 5.0の場合

003.png

004.png

■プロジェクトの設定

◇.NET Core 3.1の場合

プロジェクトを右クリック、「プロパティ」で「対象のフレームワーク」を.NET Core 3.1に設定します。
005.png

◇.NET 5.0の場合

プロジェクトを右クリック、「プロパティ」で「対象のフレームワーク」を.NET 5.0に設定します。
006.png

プロジェクトをダブルクリックし、
csprojファイルのSdkがMicrosoft.NET.Sdk.WindowsDesktopになっていたらMicrosoft.NET.Sdkに編集します。
007.png

■メイン画面の枠組み作成

Gridを分割し、上にタブ、下に閉じるボタンを配置します。
010.png

MainWindow.xaml
<Windowx:Class="RegexTester.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:local="clr-namespace:RegexTester"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"Title="Regex Tester .NET"Width="800"Height="450"ResizeMode="CanResizeWithGrip"mc:Ignorable="d"><Grid><Grid.RowDefinitions><!--  タブ行  --><RowDefinition/><!--  ボタン行  --><RowDefinitionHeight="Auto"/></Grid.RowDefinitions><TabControlMargin="6"><TabItemHeader="マッチング"></TabItem><TabItemHeader="ヘルプ"></TabItem></TabControl><StackPanelGrid.Row="1"><ButtonWidth="150"Margin="12,6"HorizontalAlignment="Right"Content="閉じる(_C)"/></StackPanel></Grid></Window>

■画面パーツ用意

015_.png
プロジェクトを右クリック、「追加」-「新しいフォルダー」でViewsと入力してください。
「Views」フォルダー内にPagesフォルダーを作成してください。

020_.png
「Pages」フォルダーを右クリック、「追加」-「ユーザーコントロール(WPF)」でMatchingContentと入力してください。
同様に「Pages」フォルダにユーザーコントロールHelpContentを追加してください。
025_2.png

■タブのコンテンツ組み込み

追加したコントロールをメイン画面の各タブで参照します。

MainWindow.xamlのWindowに
xmlns:page="clr-namespace:RegexTester.Views.Pages"を追加してください。

MainWindow.xaml
<Window:xmlns:page="clr-namespace:RegexTester.Views.Pages":

そして、TabItemの中にpage:の後に先ほど追加したユーザーコントロールの名前を書きます。

MainWindow.xaml
<TabControlMargin="6"><TabItemHeader="マッチング"><page:MatchingContent/></TabItem><TabItemHeader="ヘルプ"><page:HelpContent/></TabItem></TabControl>

pageの部分は任意の名前を付けられます。
xmlns:abc="clr-namespace:RegexTester.Views.Pages"としていたら
<abc:MatchingContent />という書き方でPagesフォルダのコントロールを参照できます。

ここまでで一度ビルドしておきましょう。

■ヘルプ内容作成

◇画面

「ヘルプ」タブに表示する内容を作ります。
HTMLのテーブル風のリファレンスとURLリンクを作ります。
030.png

Xamlの書き方もHTMLのTableと少し似ています。

HelpContent.xaml
<UserControlx:Class="RegexTester.Views.Pages.HelpContent"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:local="clr-namespace:RegexTester.Views.Pages"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"d:DesignHeight="500"d:DesignWidth="800"mc:Ignorable="d"><FlowDocumentScrollViewer><FlowDocument><Section><Paragraph><Bold>■正規表現クイックリファレンス</Bold></Paragraph><TableFontFamily="JetBrains Mono, Cascadia Code, BIZ UDGothic, Yu Gothic Medium, Meiryo"><Table.Resources><StyleTargetType="TableCell"><SetterProperty="BorderBrush"Value="Silver"/><SetterProperty="BorderThickness"Value="0.5"/></Style></Table.Resources><Table.Columns><TableColumnWidth="*"/><TableColumnWidth="4*"/></Table.Columns><TableRowGroup><TableRow><TableCell><Paragraph>.</Paragraph></TableCell><TableCell><Paragraph>任意の1文字</Paragraph></TableCell></TableRow></TableRowGroup><TableRowGroup><TableRow><TableCell><Paragraph>*</Paragraph></TableCell><TableCell><Paragraph>直前の要素の0回以上繰り返し</Paragraph></TableCell></TableRow></TableRowGroup><TableRowGroup><TableRow><TableCell><Paragraph>+</Paragraph></TableCell><TableCell><Paragraph>直前の要素の1回以上繰り返し</Paragraph></TableCell></TableRow></TableRowGroup><TableRowGroup><TableRow><TableCell><Paragraph>?</Paragraph></TableCell><TableCell><Paragraph>直前の要素の0~1回繰り返し</Paragraph></TableCell></TableRow></TableRowGroup><TableRowGroup><TableRow><TableCell><Paragraph>^</Paragraph></TableCell><TableCell><Paragraph>行頭</Paragraph></TableCell></TableRow></TableRowGroup><TableRowGroup><TableRow><TableCell><Paragraph>$</Paragraph></TableCell><TableCell><Paragraph>行末</Paragraph></TableCell></TableRow></TableRowGroup><TableRowGroup><TableRow><TableCell><Paragraph>{🥝}</Paragraph></TableCell><TableCell><Paragraph>直前の要素の🥝回繰り返し</Paragraph></TableCell></TableRow></TableRowGroup><TableRowGroup><TableRow><TableCell><Paragraph>{🥝,}</Paragraph></TableCell><TableCell><Paragraph>直前の要素の🥝回以上繰り返し</Paragraph></TableCell></TableRow></TableRowGroup><TableRowGroup><TableRow><TableCell><Paragraph>{🥝,🍉}</Paragraph></TableCell><TableCell><Paragraph>直前の要素の🥝~🍉回繰り返し</Paragraph></TableCell></TableRow></TableRowGroup><TableRowGroup><TableRow><TableCell><Paragraph>[🥝]</Paragraph></TableCell><TableCell><Paragraph>🥝内の任意の1文字</Paragraph></TableCell></TableRow></TableRowGroup><TableRowGroup><TableRow><TableCell><Paragraph>[^🥝]</Paragraph></TableCell><TableCell><Paragraph>🥝内にない任意の1文字</Paragraph></TableCell></TableRow></TableRowGroup><TableRowGroup><TableRow><TableCell><Paragraph>[🥝-🍉]</Paragraph></TableCell><TableCell><Paragraph>文字範囲🥝から🍉までの任意の1文字</Paragraph></TableCell></TableRow></TableRowGroup><TableRowGroup><TableRow><TableCell><Paragraph>()</Paragraph></TableCell><TableCell><Paragraph>グループ</Paragraph></TableCell></TableRow></TableRowGroup><TableRowGroup><TableRow><TableCell><Paragraph>(?:🥝)</Paragraph></TableCell><TableCell><Paragraph>非キャプチャ グループ</Paragraph></TableCell></TableRow></TableRowGroup><TableRowGroup><TableRow><TableCell><Paragraph>
                                    (?&lt;🍇&gt;🥝)
                                </Paragraph></TableCell><TableCell><Paragraph>名前付きグループ。🍇がグループ名</Paragraph></TableCell></TableRow></TableRowGroup></Table></Section><Section><Paragraph><Bold>■もっと詳しく</Bold></Paragraph><Paragraph><HyperlinkNavigateUri="https://docs.microsoft.com/ja-jp/dotnet/standard/base-types/regular-expressions"RequestNavigate="Hyperlink_RequestNavigate">
                        .NET の正規表現 | Microsoft Docs
                    </Hyperlink></Paragraph></Section></FlowDocument></FlowDocumentScrollViewer></UserControl>

◇ロジック

◎.NET Frameworkの場合

HelpContent.xaml.cs
usingSystem.Windows.Controls;usingSystem.Windows.Navigation;namespaceRegexTester.Views.Pages{/// <summary>/// HelpContent.xaml の相互作用ロジック/// </summary>publicpartialclassHelpContent:UserControl{publicHelpContent(){InitializeComponent();}privatevoidHyperlink_RequestNavigate(objectsender,RequestNavigateEventArgse){// URLを開くSystem.Diagnostics.Process.Start(e.Uri.AbsoluteUri);}}}

◎.NET Core 3.1 / .NET 5.0の場合

HelpContent.xaml.cs
usingSystem.Windows.Controls;usingSystem.Windows.Navigation;namespaceRegexTester.Views.Pages{/// <summary>/// HelpContent.xaml の相互作用ロジック/// </summary>publicpartialclassHelpContent:UserControl{publicHelpContent(){InitializeComponent();}privatevoidHyperlink_RequestNavigate(objectsender,RequestNavigateEventArgse){varp=newSystem.Diagnostics.Process();p.StartInfo.FileName=e.Uri.AbsoluteUri;p.StartInfo.UseShellExecute=true;// URLを開くp.Start();}}}

作り終わったらビルドし、MainWindowで「ヘルプ」タブを選択してみましょう。
ちゃんと「ヘルプ」タブ内に表示されました。
035.png

■メインコンテンツ作成

「マッチング」タブに表示する内容を作ります。
040.png

MatchingContent.xaml
<UserControlx:Class="RegexTester.Views.Pages.MatchingContent"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:local="clr-namespace:RegexTester.Views.Pages"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"d:DesignHeight="450"d:DesignWidth="800"mc:Ignorable="d"><UserControl.Resources><StyleTargetType="Label"><SetterProperty="Margin"Value="6,6,6,0"/></Style><StyleTargetType="TextBox"><SetterProperty="Margin"Value="6,0,6,6"/><SetterProperty="FontFamily"Value="JetBrains Mono, Cascadia Code, BIZ UDGothic, Yu Gothic Medium, Meiryo"/></Style><StyleTargetType="CheckBox"><SetterProperty="Margin"Value="6"/></Style></UserControl.Resources><Grid><Grid.RowDefinitions><!--  上部(検索文字列)  --><RowDefinitionHeight="Auto"MinHeight="60"/><!--  スプリッター  --><RowDefinitionHeight="Auto"/><!--  下部(正規表現パターン~結果)  --><RowDefinition/></Grid.RowDefinitions><Grid><Grid.RowDefinitions><RowDefinitionHeight="Auto"/><!--  文字列テキスト行  --><RowDefinition/></Grid.RowDefinitions><LabelContent="文字列(_I)"Target="{Binding ElementName=InTxt}"/><TextBoxx:Name="InTxt"Grid.Row="1"AcceptsReturn="True"AcceptsTab="False"Text=""TextWrapping="Wrap"VerticalScrollBarVisibility="Visible"/></Grid><GridSplitterGrid.Row="1"Height="6"Margin="0,1"HorizontalAlignment="Stretch"/><GridGrid.Row="2"><Grid.RowDefinitions><RowDefinitionHeight="Auto"/><!--  結果のテキスト行  --><RowDefinition/></Grid.RowDefinitions><StackPanel><LabelContent="正規表現パターン(_P)"Target="{Binding ElementName=RegPtn}"/><TextBoxx:Name="RegPtn"Text=""/><StackPanelOrientation="Horizontal"><CheckBoxx:Name="ROptIgnoreCase"Content="大文字小文字の区別をしない(_O)"/><CheckBoxx:Name="ROptMultiLine"Content="複数行モード(_M)"/><CheckBoxx:Name="ROptSingleLine"Content="単一行モード(_S)"/><ButtonMargin="12,0"Padding="18,0"Click="RunButton_Click"Content="実行(_E)"ToolTip="マッチングを実行します"/></StackPanel><LabelContent="結果(_R)"Target="{Binding ElementName=OutTxt}"/></StackPanel><TextBoxx:Name="OutTxt"Grid.Row="1"IsReadOnly="True"Text=""VerticalScrollBarVisibility="Visible"/></Grid></Grid></UserControl>
MatchingContent.xaml.cs
usingSystem;usingSystem.Text;usingSystem.Text.RegularExpressions;usingSystem.Windows;usingSystem.Windows.Controls;namespaceRegexTester.Views.Pages{/// <summary>/// MatchingContent.xaml の相互作用ロジック/// </summary>publicpartialclassMatchingContent:UserControl{publicMatchingContent(){InitializeComponent();}/// <summary>/// 実行ボタンクリック/// </summary>/// <param name="sender"></param>/// <param name="e"></param>privatevoidRunButton_Click(objectsender,RoutedEventArgse){this.IsEnabled=false;ExecuteMatching(InTxt.Text,RegPtn.Text,GetRegexOptions());this.IsEnabled=true;}/// <summary>/// マッチング実行/// </summary>/// <param name="input">文字列</param>/// <param name="regPattern">正規表現パターン</param>/// <param name="regOpt">検索オプション</param>publicvoidExecuteMatching(stringinput,stringregPattern,RegexOptionsregOpt){OutTxt.Clear();// 未入力がないかチェックif(IsAnyNullOrEmpties(input,regPattern)){MessageBox.Show("未入力の項目があります。");return;}try{varreg=newRegex(regPattern,regOpt);// マッチング実行MatchCollectionmatches=reg.Matches(input);if(matches.Count==0){OutTxt.Text="★マッチなし★";return;}varsb=newStringBuilder();sb.Append($"★{matches.Count}件マッチ★\n");foreach(Matchminmatches){sb.Append($"{m.Value}\n");}sb.Append("--------------------\n");sb.Append("【グループ名】\n");foreach(Matchminreg.Matches(input)){foreach(stringgNameinreg.GetGroupNames()){sb.Append($"{gName} => {m.Groups[gName].Value}\n");}}// 結果を設定OutTxt.Text=sb.ToString();}catch(Exceptionex){MessageBox.Show(ex.ToString());}}/// <summary>/// 未入力チェック/// </summary>/// <param name="values"></param>/// <returns>全部入力されていればfalse</returns>privateboolIsAnyNullOrEmpties(paramsstring[]values){foreach(stringvalueinvalues){if(string.IsNullOrEmpty(value)){// 未入力returntrue;}}returnfalse;}/// <summary>/// 画面から正規表現オプション取得/// </summary>/// <returns></returns>privateRegexOptionsGetRegexOptions(){varopt=RegexOptions.None;// 大文字小文字の区別をしないif(ROptIgnoreCase.IsChecked==true){opt|=RegexOptions.IgnoreCase;}// 複数行モードif(ROptMultiLine.IsChecked==true){opt|=RegexOptions.Multiline;}// 単一行モードif(ROptSingleLine.IsChecked==true){opt|=RegexOptions.Singleline;}returnopt;}}}

作り終わったらビルドし、MainWindowで「マッチング」タブを見てみましょう。

■メイン画面外枠部分の実装

「閉じる」ボタンの処理を書きます。

MainWindow.xaml
:
<StackPanelGrid.Row="1"><ButtonWidth="150"Margin="12,6"HorizontalAlignment="Right"Click="CloseButton_Click"Content="閉じる(_C)"/></StackPanel>
MainWindow.xaml.cs
usingSystem.Windows;namespaceRegexTester{/// <summary>/// MainWindow.xaml の相互作用ロジック/// </summary>publicpartialclassMainWindow:Window{publicMainWindow(){InitializeComponent();}privatevoidCloseButton_Click(objectsender,RoutedEventArgse){Close();}}}

■実行

「文字列」のテキストボックスに検索対象の文字列を入力し、
「正規表現パターン」のテキストボックスに検索する正規表現を入力し、実行ボタンを押します。
045.png
050_.png
055.png
060.png

おしまい


<< 最初の記事  < 前の記事  次の記事 >


Viewing all articles
Browse latest Browse all 9707

Trending Articles