「ロナえる」の夫です。
本記事では、inkscapeを利用して、自由にデザインしたものをボタンとして設置します。
やること
- inkscapeでデザインを作成
- VisualStudioを使って、WPFにデザインを取り込む
環境
- Windows 11
- Inkscape 1.2.1
- Visual Studio 2022
1. inkscapeのダウンロード
こちらの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」が表示されます!!!
全ソースファイルはこちらにアップロードしています。
おわりに
途中色々と端折りましたが、よくわからなかった方は質問してもらえれば答えます。
また、マウスホバーやクリックのアニメーションが今回はなかったですが、別途記事にできればと思います。