とりあえずログイン画面を作ってみた。
正直、販売管理システムやワークフローシステムなどを作るのにWPFが適しているかいまだに疑問ではある。
個人的には作ってみたいが、Windowsフォームのほうが安定しているし、メンバーも集めやすいし、アニメーションにこだわる必要など皆無。カーソルの動きやフォーカスの当て方などをいろいろ用途によって変える必要があるのでMVVMの分離も一癖ある。
特殊な独自コントロールもほとんど必要ない。
趣味でやるのならこだわってみてもいいが、原価やコストなどを考えるとWPFでやるメリットを見いだせない。
とかいろいろ考えているとお勉強にならないのでとりあえず趣味の範囲で組んでみようと思う。
まずコントロールの配置のためのパネルをどうするかで悩んだ。
Gridで綺麗に分けることができればいいが、項目一つ一つにGridの列や行を定義するのはめんどくさい。項目が増えた時に変更箇所も多い。
ということで、Gridをベースとしてその上にCanvasコントロールを配置することにした。
Login.xaml
<Window x:Class="SystemSample.win00_0000"
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:SystemSample"
xmlns:control="clr-namespace:SystemSample.Controls"
mc:Ignorable="d"
Title="ログイン画面" Height="250" Width="450" Style="{StaticResource LoginWindowStyle}" WindowStartupLocation="CenterScreen">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="5"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="5"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="5"/>
<RowDefinition Height="*"/>
<RowDefinition Height="5"/>
</Grid.RowDefinitions>
<Canvas Grid.Column="1" Grid.Row="1">
<Label x:Name="lblTitle" Content="販売管理システム" Canvas.Left="10" Canvas.Top="10" Width="412" FontSize="32" FontFamily="Arphic Kaisho4JIS" VerticalContentAlignment="Center" HorizontalContentAlignment="Center" />
<control:CsTextBox x:Name="txtUserID" Canvas.Left="167" Text="{Binding UserID}" Canvas.Top="79" Width="205" Style="{StaticResource NormalTextBox}"/>
<control:CsTextBox x:Name="txtPass" Canvas.Left="167" Text="{Binding PassWord}" Canvas.Top="108" Width="205" Style="{StaticResource NormalTextBox}"/>
<Label x:Name="lblUserID" Content="ユーザーID" Canvas.Left="60" Canvas.Top="79" Width="105" Style="{StaticResource RequiredLabel}"/>
<Label x:Name="lblPass" Content="パスワード" Canvas.Left="60" Canvas.Top="108" Width="105" Style="{StaticResource RequiredLabel}" />
<Button x:Name="btnLogin" Content="ログイン" Canvas.Left="280" Canvas.Top="159" Width="95" Style="{StaticResource NormalButton}" />
</Canvas>
</Grid>
</Window>
CsTextBoxはTextBoxを継承しただけの独自コントロール。
まだ何の制御も実装していない。
本当は数値入力のみとか半角英数字のみ入力できるようにするなど実装したいがそれはそのうちということで。
StaticResourceについてはプロジェクト内でスタイルを共通化したいので、App.xamlに定義を行っている。
・App.xaml
<Application x:Class="SystemSample.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:SystemSample"
xmlns:controls="clr-namespace:SystemSample.Controls"
StartupUri="win00_0000.xaml">
<Application.Resources>
<!--#region 色など-->
<!-- Active状態の背景色 -->
<SolidColorBrush x:Key="ActiveBackColor" Color="Yellow"></SolidColorBrush>
<!-- テーマカラー -->
<LinearGradientBrush x:Key="BlueGradientBrush" EndPoint="0,1" StartPoint="0,0">
<GradientStop Color="#FFFFFFFF" Offset="0"/>
<GradientStop Color="#FFC4DDFF" Offset="0.987"/>
<GradientStop Color="#FFDEECFF" Offset="0.535"/>
</LinearGradientBrush>
<!--#endregion-->
<!--#region 継承元のスタイル-->
<!-- 継承元のフォームベースのスタイル -->
<Style x:Key="WindowStyleBase" TargetType="Window">
<Setter Property="FontFamily" Value="MS Gothic" />
<Setter Property="FontSize" Value="15"/>
<Setter Property="Background" Value="{StaticResource BlueGradientBrush}"></Setter>
<Setter Property="WindowStyle" Value="SingleBorderWindow"></Setter>
</Style>
<Style x:Key="CsTextBoxStyleBase" TargetType="controls:CsTextBox">
<Setter Property="FontFamily" Value="MS Gothic" />
<Setter Property="FontSize" Value="15"/>
<Setter Property="TextAlignment" Value="Left"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Height" Value="25"/>
<Style.Triggers>
<!-- フォーカス時の背景色 -->
<Trigger Property="IsFocused" Value="True">
<Setter Property="Background" Value="{StaticResource ActiveBackColor}"></Setter>
</Trigger>
</Style.Triggers>
</Style>
<Style x:Key="TextBlockStyleBase" TargetType="TextBlock">
<Setter Property="FontFamily" Value="MS Gothic" />
<Setter Property="FontSize" Value="15"/>
<Setter Property="TextAlignment" Value="Left"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="Height" Value="25"/>
</Style>
<Style x:Key="LabelStyleBase" TargetType="Label">
<Setter Property="FontFamily" Value="MS Gothic" />
<Setter Property="FontSize" Value="15"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="BorderBrush" Value="Black"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Height" Value="25"/>
</Style>
<Style x:Key="ButtonStyleBase" TargetType="Button">
<Setter Property="FontFamily" Value="MS Gothic" />
<Setter Property="FontSize" Value="15"/>
<Setter Property="BorderBrush" Value="Black"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Height" Value="25"/>
<Setter Property="Background" >
<Setter.Value>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="Gainsboro" Offset="0"/>
<GradientStop Color="#FF919191" Offset="1"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
<Style.Triggers>
<!-- フォーカス時の背景色 -->
<Trigger Property="IsFocused" Value="True">
<Setter Property="Background" Value="{StaticResource ActiveBackColor}"></Setter>
</Trigger>
</Style.Triggers>
</Style>
<!--#endregion -->
<!--#region 継承後のスタイル-->
<Style x:Key="NormalLabel" TargetType="Label" BasedOn="{StaticResource LabelStyleBase}">
</Style>
<Style x:Key="RequiredLabel" TargetType="Label" BasedOn="{StaticResource LabelStyleBase}">
<!--<Setter Property="Background" Value="#FFFF997B" />-->
<Setter Property="Background" Value="#FF7BB7FF" />
</Style>
<Style x:Key="NormalTextBox" TargetType="controls:CsTextBox" BasedOn="{StaticResource CsTextBoxStyleBase}">
</Style>
<Style x:Key="NormalTextBlock" TargetType="TextBox" BasedOn="{StaticResource TextBlockStyleBase}">
</Style>
<Style x:Key="NormalButton" TargetType="Button" BasedOn="{StaticResource ButtonStyleBase}">
</Style>
<Style x:Key="LoginWindowStyle" TargetType="Window" BasedOn="{StaticResource WindowStyleBase}">
<!--<Setter Property="Background">
<Setter.Value>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
<LinearGradientBrush.GradientStops>
<GradientStop Offset="0.0" Color="#FFB0FFB0"/>
--><!--<GradientStop Offset="1.0" Color="#FFD6D6D6"/>--><!--
<GradientStop Offset="1.0" Color="#FFB6DAA2"/>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Setter.Value>
</Setter>-->
</Style>
<Style x:Key="MenuWindowStyle" TargetType="Window" BasedOn="{StaticResource WindowStyleBase}">
</Style>
<!--#endregion-->
</Application.Resources>
</Application>
Styleを継承するにはBaseOnを指定することでできる。
そのため、各コントロールのBaseStyleを定義し、それらを継承したスタイルを個別に作成するようにしている。
また、コントロールにフォーカスがあるときにはコントロールの背景色を変更したいので、Triggerを定義している。
どこかのタイミングでプロジェクトを上げたいと思う。