前回は .NETでSPA(SinglePageApplication)を実現できるWebフレームワークの BlazorWebAssemblyでTodo画面を作成しました。 今回はMatBlazorを使って、そのTodo画面をマテリアルデザインにしてみました。
MatBlazor使ったらどうなるの?
こんな感じの画面が
こんな感じの画面になっちゃいます。
ソースコードは下記に置いてます。
前準備
まずは前準備としてMatBlazorのパッケージを追加し、使用できるように設定していきます。
◆ パッケージの追加
下記のコマンドでパッケージを追加します。念のためcsprojに追加されていることを確認しておきましょう。
$ dotnet add package MatBlazor
◆ _imports.razorを編集
下記を追加します。
_imports.razor
@using MatBlazor
◆ wwwroot/index.htmlを編集
下記を追加します。
index.html
<body>
<div id="app">Loading...</div>
<div id="blazor-error-ui">
An unhandled error has occurred.
<a href="" class="reload">Reload</a>
<a class="dismiss">🗙</a>
</div>
<script src="_framework/blazor.webassembly.js"></script>
<!-- 下記を追加 -->
<script src="_content/MatBlazor/dist/matBlazor.js"></script>
</body>
これで準備は整いました。
Todoアイテム入力欄
ここではチェックボックス、入力欄、ボタンにMatBlazorを使用しています。
TodoMat.razor
@page "/todomat"
<style>
.new-item-text-field > label.mat-text-field > span {
margin-left: 30px;
}
</style>
<h1>Todo</h1>
<div class="new-item-text-field" style="display: flex; position: relative; align-items: center;">
<MatCheckbox Style="z-index: 1; position: absolute; left: 0;"
@bind-Value="allChecked" Disabled="@(!TodoItemExists())"></MatCheckbox>
<MatTextField @bind-Value="newItem" Label="What needs to be done?"
OnKeyDown="@Enter" OnInput="@OnInput"
Style="z-index: 0; width: 500px; padding-left: 50px;"></MatTextField>
<MatButton OnClick="@AddItem" Outlined="true">add</MatButton>
</div>
MatBlazorのドキュメントに使用例がたくさん載ってるのでさらっと説明を。
◆ MatCheckbox
チェックボックスのコンポーネント。前回作成したTodo画面では入力欄のとこにチェックボックスを付けてなかったのですが追加しました。
Name | Description |
---|---|
@bind-Value | バインドする値。true / false |
Disabled | 無効にするかどうか。true / false |
@bind-Value
には、プロパティallCheckedをバインド。
コメントの通りです。
Disabled
には、メソッドTodoItemExists()の戻り値をバインド。
TodoMat.cs
// newItemのチェック状態
private bool allChecked
{
get
{
// 未完了アイテムがない場合にチェックON、一つでもあればチェックOFF
return !allTodos.Any(x => !x.IsDone);
}
set
{
// チェック状態に合わせてTodoアイテムすべてのチェック状態を変更
allTodos.ForEach(x => x.IsDone = value);
}
}
/// <summary>
/// Todoアイテムが存在するかどうか
/// </summary>
/// <returns></returns>
private bool TodoItemExists()
{
return allTodos.Any();
}
◆ MatTextField
テキストフィールドのコンポーネント。
Name | Description |
---|---|
@bind-Value | バインドする値。入力した値を保持。 |
Label | 入力項目名。今回はPlaceholder的な使い方してます。 HelperTextというのが別に用意されているので本来はこちらの方がいいのかな? |
OnKeyDown | キーダウンイベント。 |
OnInput | 入力イベント。 |
ただ1個だけ面倒だったのがあります。
MatTextFieldのLabel
「What needs to be done?」の文字の位置。
CheckBoxとTextFieldを重ねてるので入力内容はStyle属性で
paddingを指定してやればズラせたのですが
Label
の文字位置は用意されてる属性では触れそうになかったので
Styleを強引にイジってます。(上記ソースの4-6行目)
これが正解なのかどうかわかりませんがまたどっかで時間作って確認してみます。
◆ MatButton
ボタンのコンポーネント。
Name | Description |
---|---|
OnClick | クリックイベント。 |
Outlined | ボタンの枠を表示するかどうか。 |
Todoアイテムリスト
リスト用コンポーネント。MatListとMatListItemを使用してます。今回はStyleのみ指定。
TodoMat.razor
<style>
.completed-todo-item {
text-decoration: line-through;
color: lightgray !important;
}
</style>
・・・
・・・
<MatList Style="width: 500px">
@foreach (var item in todosForDisplay)
{
<MatListItem Style="padding: 0;">
<MatCheckbox Style="z-index: 1;" @bind-Value="item.IsDone"></MatCheckbox>
<MatStringField Style="z-index: 0; width: 100%; position: absolute; padding-left: 50px;"
InputClass="@GetCompletedTodoItemCssClass(item.IsDone)"
@bind-Value="item.Content"></MatStringField>
</MatListItem>
}
</MatList>
MatListItem内ではMatCheckboxとMatStringFieldを使用しています。 MatStringFieldはMatTextFieldと違ってString型専用のコンポーネントっぽいです。 MatTextFieldはintやDateTimeなどの型がバインドできます。
◆ MatStringField
String専用の入力用コンポーネント。
Name | Description |
---|---|
InputClass | input要素のCSSクラス。 |
Styleに「completed-todo-item」を用意し、InputClass
に
チェック状態によって異なるStyle名を返すメソッド「GetCompletedTodoItemCssClass()」をバインドしています。
TodoMat.cs
/// <summary>
/// Todo完了アイテムCSSクラス名を取得
/// </summary>
/// <param name="isDone">完了フラグ</param>
/// <returns>クラス名</returns>
private string GetCompletedTodoItemCssClass(bool isDone)
{
return isDone ? "completed-todo-item" : "";
}
リスト下のボタン群
ボタン用のコンポーネント。
TodoMat.razor
@allTodos.Count(x => !x.IsDone) items left
<MatButton OnClick="@ShowAll" Outlined="true" Style="margin-left: 20px">All</MatButton>
<MatButton OnClick="@ShowActive" Outlined="true">Active</MatButton>
<MatButton OnClick="@ShowCompleted" Outlined="true" Style="margin-right: 20px">Completed</MatButton>
<MatButton OnClick="@ClearCompleted" Outlined="true"
Disabled="@(!CompletedTodoItemExists())">Clear completed</MatButton>
TodoMat.cs
/// <summary>
/// 完了済みのTodoアイテムが存在するかどうか
/// </summary>
/// <returns></returns>
private bool CompletedTodoItemExists()
{
return allTodos.Any(x => x.IsDone);
}
さいごに
使ってみた感じ、CSSの知識がない人にとっては嬉しいとは思いますが Webの知識がある人からすると物足りなさそうな感じがします。 ちょっと細かいことに拘るとCSSの知識も必要になってきます。 ドキュメントはわかりやすかったのですんなり使えました。 他にもBlazor向けのコンポーネントで良さそうなのがあったらまた紹介したいと思います。
以上、もりもりでした。
0 件のコメント:
コメントを投稿