programming

C# Tech

【C#】WPFで自作デザインのボタンを作成

「ロナえる」の夫です。

本記事では、inkscapeを利用して、自由にデザインしたものをボタンとして設置します。

やること

  • inkscapeでデザインを作成
  • VisualStudioを使って、WPFにデザインを取り込む

環境

  • Windows 11
  • Inkscape 1.2.1
  • Visual Studio 2022

1. inkscapeのダウンロード

https://inkscape.org/

こちらのURLから自分の環境にあったinkscapeをダウンロードしてください。

僕の環境だと次のようにダウンロードしてしています。

「Download」→「Current Version」→「Windows」→「64-bit」→「Installer in .exe format」

2. inkscapeのインストール

僕の環境では、exeファイルを使ってインストールしています。

基本的には、デフォルトのまますべて進めてもらえばOKです。

3. inkscapeでデザイン

今回、作成していくデザインは

3-1. 新規ドキュメント

「新規ドキュメント」を開いてください。

3-2. 円を描く

左のツールバーにある赤い丸「◎」をクリックしてください。

これで、円を描くことができるようになるので、適当な大きさの円を描いてください。

円の大きさは、「水平半径」「垂直半径」で調整することができます。

今回は両方50にして、きれいな真円にしておきます。

円の大きさはWPFに移植する時点で調整することができます。

3-3. 文字を入力

「Button」の文字を入力していきます。

左のツールバーから「テキストツール」を選択し、適当な位置を左クリックします。

クリックすると、文字を入力できるので、「Button」と入力します。

入力後は、「Button」を右クリックして、「テキストとフォント」を選択します。

今回は、各パラメータを下記のようにしました。

  • フォント:sans-serif
  • スタイル:Normal
  • フォントサイズ:56

3-4. 整列・位置の調整

円と「Button」を揃えていきましょう。

次に、円と「Button」を揃えていきましょう。

「オブジェクト」→「整列と配置」を選択します。

円と「Button」を「Shift」を押しながらそれぞれクリックします。

選択状態になるので、右に出てきた「整列と配置」のパレットで、水平/垂直方向それぞれの中央寄せを選択します。

これで、円と「Button」がきれいに合わさりました。

だいぶいい感じになったのですが、

左ツールバーにある「↖」を選択して、先ほど描いた円と文字を「Shift」を押しながらクリックします。

このままだと、Xamlにもっていったときに、ボタン自体の位置がずれて扱いずらいので、左端に寄せます。

その後、「x」と「y」の位置を0にしてください。

3-5. 保存(Xaml)

最後に、描いた円をXamlとして出力します。

「ファイル」→「名前を付けて保存」を選択します。

ファイル保存のダイアログが表示されるので、ファイル名を入力します。

「ファイル名」を入力し、「ファイルの種類」を「Microsoft XAML」を選択してください。

これでデザインの保存が完了しました!!!

続いて、WPFに移植していきます。

4. WPFの実装

4-1. 新規作成

まずは、VisualStudioでプロジェクトを新規作成します。

「WPF Application」を選択します。

今回は、「Project name」は「SampleApp」とします。

「Framework」はDeaultのまま、「.Net 6.0」を選択します(環境に合わせてください)。

4-2. Inkscapeで作ったXamlファイルを追加

まずは、ソースがあるフォルダに先ほど作った「circle.xaml」を移動させます。

(わかりやすさのためだけなので、移動させなくてもOKです!)

プロジェクトに追加します。

プロジェクトを右クリックし、

「Add」→「Existing Item」

(日本語だと、「追加」→「既存のファイル」だと思います。)

で「circle.xaml」を追加します。

4-4. カスタムボタンを作成 ~ソースファイル作成~

ここからは、先ほど作成した「circle.xaml」を基にカスタムしたボタンを作成していきます。

まずは、新しくUserControlを追加していきます。

続いて、「UserControl(WPF)」を選択します。

今回は、「CircleButton」という名前にします。

一部コメントを追加していますが、おおよそこのようなソースファイルが生成されると思います。

<UserControl
~中略~
>
<!-- ②-->
  <Grid>
  <!-- ①-->
  </Grid>
<UserControl>

上記の、①、②にカスタムしたボタンを表示するためのコードを追加していきます。

4-4. カスタムボタンを作成 ~ソースコードの追記~

①の部分には、Buttonタグを追加します。

<Grid>
    <Button Style="{StaticResource CircleButtonStyle}"/>
</Grid>

CircleButtonStyleはないと、警告が出ると思いますが、こちらの内容を、②に記述していきます。

②にはまず、<UserControl.Resource>タグCircleButtonStyleの定義を追加します。

<UserControl.Resources>
  <Style x:Key="CircleButtonStyle" TargetType="Button">
    <Setter Property="Template" Value="{StaticResource DefaultTemplate}"/>
  </Style>
</UserControl.Resources>

さらに、DefaultTemplateというものを参照しましたが、こちらをcircle.xamlの内容を基に定義します。

まずは、circle.xamlの必要なところを加工していきます。

色々端折りますが、必要なところだけ抜き取り、CanvasをGridに変えて、少し加筆してあげるとこのようになります。

<Viewbox xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" Stretch="Uniform">
  <Grid Width="100" Height="100">
    <Grid Name="layer1">
      <Ellipse Width="100" Height="100" Fill="#FF000000" StrokeThickness="0.264583"/>
      <TextBlock VerticalAlignment="Center" HorizontalAlignment="Center" FontSize="30" FontWeight="Normal" FontFamily="sans-serif" FontStyle="normal" Foreground="#FFFFFFFF" >Button</TextBlock>
    </Grid>
  </Grid>
</Viewbox>

こちらを、DefaultTempleteとして定義すると、下記のようになります。

<ControlTemplate x:Key="DefaultTemplate" TargetType="Button">
  <Viewbox xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" Stretch="Uniform">
    <Grid Width="100" Height="100">
      <Grid Name="layer1">
        <Ellipse Width="100" Height="100" Fill="#FF000000" StrokeThickness="0.264583"/>
        <TextBlock VerticalAlignment="Center" HorizontalAlignment="Center" FontSize="30" FontWeight="Normal" FontFamily="sans-serif" FontStyle="normal" Foreground="#FFFFFFFF" >Button</TextBlock>
      </Grid>
    </Grid>
  </Viewbox>
</ControlTemplate>

こちらを、UserControl.Resourcesタグの直下に追加すればカスタムボタンは完成です。

全体はこちらのGithubを参考にしてください。

Inkscapeで作成したものから結構変更したので、最初からVisual Studioで作ればよいのではと思われる方もいらっしゃると思いますが、Xamlだけで直観的にデザインするのが難しかったため、こういう方法をとっています。

4-5. ボタンを追加

まずは、不要になった「circle.xaml」をプロジェクトから除外します。

「ソリューションエクスプローラー」の「circle.xaml」に対して右クリックすると、

除外できる項目があると思うので、そちらで除外してください。

では、「MainWindow.xaml」にボタンを追加していきます。

「ToolBox」を開き、表示された「CircleButton」をドラッグ&ドロップで、好きなところに設置します。

すぐ表示されなかった場合は、一度Buildが必要かもしれません。

4-6. ボタンを実行してみる

最後に、ボタンの実行をしてみます。

ただ、今回の実装だとボタンをクリックした時の動きがないため、ボタンとして動作しているかわかりづらいと思います。

なので、ひと工夫を加えます。

CircleButton.xamlを開き、表示されたボタンのデザインをダブルクリックしてください。

すると、ButtonタグにClickというプロパティが追加されたと思います。

さらに、CircleButton.xamlに紐づいたCircleButton.xaml.csにも Button_Clickという関数が増えています。

これが、ボタンがクリックされた時に実行される関数なので、今回はMessageBoxが表示されるように実装してあげます。


MessageBox.Show("Cliecked");

ビルド&実行してあげると、先ほど作成したボタンが表示されるので、それをクリックすると、

期待通り、「Clicked」が表示されます!!!

全ソースファイルはこちらにアップロードしています。

おわりに

途中色々と端折りましたが、よくわからなかった方は質問してもらえれば答えます。

また、マウスホバーやクリックのアニメーションが今回はなかったですが、別途記事にできればと思います。

-C#, Tech,
-, , , , ,