導入
前回の一覧は空のままでした。ここにTextBoxとButtonをつなぎ、実際にタスクを追加できるようにします。ポイントは2つ——入力欄との双方向バインディング(Mode=TwoWay)と、ボタンをClickではなく第6章で作ったAddCommand(ICommand)に結びつけることです。
説明
sequenceDiagram
participant TB as TextBox
participant VM as TaskListViewModel
participant BTN as Button(AddCommand)
TB->>VM: NewTaskTitle が変わる(TwoWay)
BTN->>VM: クリック→AddCommand.Execute()
VM->>VM: Tasks.Add(...)/NewTaskTitle = ""
VM-->>TB: NewTaskTitleの変更が反映(入力欄が空になる)
<Window Title="タスク一覧" Width="360" Height="320">
<StackPanel Margin="16">
<TextBlock Text="タスク一覧" FontWeight="Bold" FontSize="16" />
<TextBox Text="{Binding NewTaskTitle, Mode=TwoWay}" Margin="0,10" />
<Button Content="追加" Command="{Binding AddCommand}" Width="80" />
<ListBox ItemsSource="{Binding Tasks}" DisplayMemberPath="Title" Height="140" Margin="0,10" />
</StackPanel>
</Window>
public record TaskDto(string Title, bool IsCompleted);
public class TaskListViewModel
{
public string NewTaskTitle { get; set; } = "";
public ObservableCollection<TaskDto> Tasks { get; set; } = new();
public ICommand AddCommand => new RelayCommand(
() => { Tasks.Add(new TaskDto(NewTaskTitle, false)); NewTaskTitle = ""; },
() => !string.IsNullOrWhiteSpace(NewTaskTitle)
);
}
Text="{Binding NewTaskTitle, Mode=TwoWay}":入力欄に打つとNewTaskTitleが変わり、NewTaskTitleが変わると入力欄の表示も変わる(双方向)Command="{Binding AddCommand}":ボタンのクリックを、コードビハインドのClickではなく第6章のRelayCommandに結びつけるAddCommandのcanExecute(() => !string.IsNullOrWhiteSpace(NewTaskTitle))がfalseを返す間、ボタンは自動的に押せなくなる(IsEnabledを自分で書く必要はない)- 実行本体(
execute)の中でNewTaskTitle = ""とすると、追加後に入力欄が自動でクリアされる
やってみよう
- 何も入力しない状態で「追加」ボタンが押せない(グレー表示)ことを確認する
- テキストボックスに何か入力すると、ボタンが押せるようになることを確認する
- 入力して「追加」を押すと、一覧に追加され、入力欄が空に戻ることを確認する
- 複数回繰り返し、一覧が増えていくことを確認する
確認ポイント
- タイトル未入力の間は「追加」ボタンが押せないこと(
canExecuteの自動反映) - 追加すると一覧(
ListBox)に反映されること - 追加後、入力欄が自動でクリアされること
まとめ
TextBoxのMode=TwoWayで、入力欄とViewModelのプロパティを双方向に結ぶButtonのCommandはClickハンドラの代わりにICommandを結びつける。canExecuteがあればIsEnabledは自動制御される- コードビハインドに1行も処理を書かずに「入力→追加→一覧反映」が完成する
次回: 一覧から完了・削除する操作をつなぎ、CanExecuteでボタンの活性/非活性を制御します。