質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.06%

C# WPF リストボックスの要素を別のリストボックスへバインド

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 435

score 9

概要

C# WPF 初心者です。
用語の誤用/的外れな質問ありましたらご容赦ください。

データバインディングを勉強しています。
リストボックス→別のリストボックスへのバインド方法をご教示願います。

質問事項_詳細

[表題]と[Memo]の要素を入力して追加ボタンを押すと、左側のリストボックスに入力内容が追加されます。
左側のリストボックスは[表題]のみ表示します。

下記画像のようにリストを選択すると、右側のリストボックスに
選択した項目の[表題]と[要素]が表示されるような仕組みにしたいです。

■画像の例
[表題]:ABC , [Memo]:DEF と入力した場合、右側のリストボックスに
ABC
DEF
と表示されるようにしたい。

![イメージ説明

以下3点ご教示願います。

  • リストボックスの選択されている項目を取得する方法
  • 取得した項目をバインドする方法
  • そもそも右側はリストボックスではなく、他のコントロールを使用した方が良いのか

※また、ソースコードに改善点ありましたらご指摘願います。

該当のソースコード

<Window x:Class="リストボックスSample.Views.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:prism="http://prismlibrary.com/"
        prism:ViewModelLocator.AutoWireViewModel="True"
        xmlns:l="clr-namespace:リストボックスSample.ViewModels"
        Title="{Binding Title}" Height="350" Width="525" >

    <Window.DataContext>
        <l:MainWindowViewModel />
    </Window.DataContext>

    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition Width="5"/>
            <ColumnDefinition Width="2*"/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="5"/>
            <RowDefinition Height="12*"/>
        </Grid.RowDefinitions>
        <TextBox x:Name="txt_Title" Grid.Column="0" Margin="43,5,10,4" Text="{Binding Txt_Title, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"  TextWrapping="Wrap"/>
        <TextBox x:Name="txt_Memo" Grid.Column="2" Margin="66,5,122,5" Text="{Binding Txt_Memo,Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" TextWrapping="Wrap"/>
        <Label x:Name="lbl_Title" Grid.Row="0" Grid.Column="0" Content="表題" HorizontalAlignment="Left" Margin="10,9,0,8" Width="35"/>
        <Label x:Name="lbl_Memo" Grid.Row="0" Grid.Column="2" Content="Memo" Margin="5,10,286,6"/>
        <Button Content="追加" Command="{Binding ExecuteCommand}" Grid.Column="2" Margin="0,9,10,10" HorizontalAlignment="Right" Width="56"/>

        <!--タスク一覧-->
        <ListBox x:Name="lst_Title" ItemsSource="{Binding Path=TaskList}" DisplayMemberPath="Title" IsSynchronizedWithCurrentItem="True"  Margin="10,5,10,15" Grid.Row="2"/>

        <!--詳細表示-->
        <ListBox x:Name="lst_Detail"  Grid.Column="2" Grid.Row="2" Margin="5,5,16,15">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel>
             <!--該当部分(ここにTitleとMemoの要素を出力したい)-->
                        <TextBlock Text="" FontWeight="Bold"/>
                        <TextBlock Text=""/>
                    </StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>

    </Grid>
</Window>
//
//ViewModel
//

using Prism.Mvvm;
using Prism.Commands;
using リストボックスSample.Views;
using System.Windows.Documents;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;

namespace リストボックスSample.ViewModels
{
    public class MainWindowViewModel : BindableBase
    {
        private string txt_Title;
        public string Txt_Title
        {
            get { return this.txt_Title; }
            set
            {
                if(this.SetProperty(ref this.txt_Title, value))
                this.ExecuteCommand.RaiseCanExecuteChanged();
            }
         }

        private string txt_Memo;
        public string Txt_Memo
        {
            get { return this.txt_Memo; }
            set
            {
                if(this.SetProperty(ref this.txt_Memo, value))
                this.ExecuteCommand.RaiseCanExecuteChanged();
            }
        }

        public ObservableCollection<Task> TaskList { get; set; }

        public DelegateCommand ExecuteCommand { get; private set; }

        public MainWindowViewModel()
        {
            this.TaskList = new ObservableCollection<Task>();

            this.ExecuteCommand = new DelegateCommand(this.Execute, this.CanExecute);
        }

        //実行コマンド
        private void Execute()
        {
            this.TaskList.Add(new Task { Title = Txt_Title, Detail = Txt_Memo });

            Txt_Title = "";
            Txt_Memo = "";

            this.ExecuteCommand.RaiseCanExecuteChanged();
        }

        //コマンド条件式
        private bool CanExecute()
        {
            if(string.IsNullOrEmpty(Txt_Title))
            {
                return false;
            }
            return true;
        }

    }
}
//
//Model
//

using System;
using System.Collections.Generic;
using System.Text;

namespace リストボックスSample.Views
{
    public class Task
    {
        public string Title { get; set; }
        public string Detail { get; set; }
    }
}
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

+1

単独選択か複数選択かで変わってきます。
見てもらったほうが早いので、それぞれ向き用の2つの表示法を用意しました。
SelectionModeをコンボボックスで切り替えられるようになっています。違いを確認してください。

<Window
  x:Class="Questions284783.Views.MainWindow"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:controls="clr-namespace:System.Windows.Controls;assembly=PresentationFramework"
  xmlns:prism="http://prismlibrary.com/"
  xmlns:sys="clr-namespace:System;assembly=mscorlib"
  Width="525"
  Height="350"
  prism:ViewModelLocator.AutoWireViewModel="True">

  <!--  prism:ViewModelLocator.AutoWireViewModel="True" があるからいらないはず  -->
  <!--<Window.DataContext>
    <l:MainWindowViewModel />
  </Window.DataContext>-->

  <Window.Resources>
    <!--  SelectionMode選択用データ(本題には無関係 違いを確認しやすいように)  -->
    <ObjectDataProvider
      x:Key="selectionMode"
      MethodName="GetValues"
      ObjectType="{x:Type sys:Enum}">
      <ObjectDataProvider.MethodParameters>
        <x:Type TypeName="controls:SelectionMode" />
      </ObjectDataProvider.MethodParameters>
    </ObjectDataProvider>
  </Window.Resources>

  <Grid>
    <Grid.ColumnDefinitions>
      <ColumnDefinition />
      <ColumnDefinition Width="2*" />
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
      <RowDefinition Height="Auto" />
      <RowDefinition />
    </Grid.RowDefinitions>

    <Grid>
      <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto" />
        <ColumnDefinition />
      </Grid.ColumnDefinitions>
      <Label
        Margin="5"
        VerticalAlignment="Center"
        Content="表題" />
      <TextBox
        Grid.Column="1"
        Margin="5"
        VerticalAlignment="Center"
        Text="{Binding Txt_Title, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
        TextWrapping="Wrap" />
    </Grid>

    <Grid Grid.Column="1">
      <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto" />
        <ColumnDefinition />
        <ColumnDefinition Width="Auto" />
      </Grid.ColumnDefinitions>
      <Label
        Margin="5"
        VerticalAlignment="Center"
        Content="Memo" />
      <TextBox
        Grid.Column="1"
        Margin="5"
        VerticalAlignment="Center"
        Text="{Binding Txt_Memo, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
        TextWrapping="Wrap" />
      <Button
        Grid.Column="2"
        MinWidth="56"
        Margin="5"
        Command="{Binding ExecuteCommand}"
        Content="追加" />
    </Grid>

    <Grid Grid.Row="1">
      <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition />
      </Grid.RowDefinitions>

      <!--  SelectionMode選択  -->
      <ComboBox
        x:Name="comboBox"
        Margin="5"
        ItemsSource="{Binding Source={StaticResource selectionMode}}"
        SelectedIndex="0" />
      <ListBox
        x:Name="lst_Title"
        Grid.Row="1"
        Margin="5"
        DisplayMemberPath="Title"
        IsSynchronizedWithCurrentItem="True"
        ItemsSource="{Binding TaskList}"
        SelectionMode="{Binding SelectedValue, ElementName=comboBox}" />
    </Grid>

    <Grid Grid.Row="1" Grid.Column="1">
      <Grid.RowDefinitions>
        <RowDefinition />
        <RowDefinition Height="Auto" />
      </Grid.RowDefinitions>

      <!--  SelectedItems をもらう  -->
      <ListBox Margin="5" ItemsSource="{Binding SelectedItems, ElementName=lst_Title}">
        <ListBox.ItemTemplate>
          <DataTemplate>
            <StackPanel>
              <TextBlock FontWeight="Bold" Text="{Binding Title}" />
              <TextBlock Text="{Binding Detail}" />
            </StackPanel>
          </DataTemplate>
        </ListBox.ItemTemplate>
      </ListBox>

      <!--  lst_Title が SelectionMode="Single" ならこれもあり  -->
      <StackPanel Grid.Row="1">
        <TextBlock
          Margin="5"
          FontWeight="Bold"
          Text="{Binding TaskList/Title}" />
        <TextBlock Margin="5" Text="{Binding TaskList/Detail}" />
      </StackPanel>
    </Grid>
  </Grid>
</Window>
using System.Collections.ObjectModel;
using Prism.Commands;
using Prism.Mvvm;

namespace Questions284783.ViewModels
{
    public class MainWindowViewModel : BindableBase
    {
        private string txt_Title;
        public string Txt_Title
        {
            get => txt_Title;
            set
            {
                if(SetProperty(ref txt_Title, value))
                    ExecuteCommand.RaiseCanExecuteChanged();
            }
        }

        private string txt_Memo;
        public string Txt_Memo
        {
            get => txt_Memo;
            set
            {
                if(SetProperty(ref txt_Memo, value))
                    ExecuteCommand.RaiseCanExecuteChanged();
            }
        }

        public ObservableCollection<Task> TaskList { get; } = new ObservableCollection<Task>();

        public DelegateCommand ExecuteCommand { get; private set; }

        public MainWindowViewModel()
        {
            // 検証時面倒なので先入れ^^;
            TaskList.Add(new Task { Title = "aaa", Detail = "111" });
            TaskList.Add(new Task { Title = "bbb", Detail = "222" });
            TaskList.Add(new Task { Title = "ccc", Detail = "333" });

            ExecuteCommand = new DelegateCommand(Execute, CanExecute);
        }

        private void Execute()
        {
            TaskList.Add(new Task { Title = Txt_Title, Detail = Txt_Memo });

            Txt_Title = "";
            Txt_Memo = "";

            ExecuteCommand.RaiseCanExecuteChanged();
        }

        private bool CanExecute() => !string.IsNullOrEmpty(Txt_Title);
    }

    public class Task
    {
        public string Title { get; set; }
        public string Detail { get; set; }
    }
}

バインディング中のスラッシュ{Binding TaskList/Title}については↓あたりを参照してください(説明放棄^^;
方法: 階層データでマスター詳細パターンを使用する - WPF | Microsoft Docs
WPF4.5入門 その56「コレクションのバインディング」 - かずきのBlog@hatena 最後のほうの「現在の選択項目をバインディングする方法」


ここまではViewだけでの対応ですが、選択されているというのが重要な情報の場合(ファイルに選択情報も保存して次回復元する等)は、別の手のほうがいいかもしれません。

Taskクラスにbool IsSelectedプロパティを用意して、lst_TitleではListBoxItemIsSelectedにバインドし、lst_DetailではListBoxItemVisibilityにバインドします。
どちらのListBoxTaskListがソースですが、lst_Detailでは未選択のものは無いように見えます。
ちょっとずるいようですが、割とポピュラーな手段だと思います。もし気になるようでしたら追記しますので言ってください。


ソースコードに改善点ありましたらご指摘願います。

prism:ViewModelLocator.AutoWireViewModel="True"があるので<l:MainWindowViewModel />で入れる必要はないはずです。

ぐちゃぐちゃMarginMargin="66,5,122,5"のようなもの)はよろしくないです(Margin="5"Margin="5,2"のようなすっきりしたものならOKです)
ユーザーのフォント設定やウィンドウのリサイズ等で、文字が見切れたりレイアウト崩れの原因になります。
はっきり言って面倒なのですが、入れ子Grid等で地道にレイアウトしてください。

Width="56"もフォントによっては見切れるので、MinWidth="56"にしておくと安心です。

C#コードは特にないです^^
ReactivePropertyを使えば、プロパティのごちゃっとしたところを緩和できそうです。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/08/15 15:30 編集

    ※長いので、別の質問として投稿したほうが良い場合はお申し付けください。

    >もし気になるようでしたら追記しますので言ってください。
    文章だけでは理解できなかったので、お手数おかけしますがコードいただけますでしょうか。

    SelectionModeをコンボボックスで切り替えられるように設定していただき、ありがとうございます。
    本題とは逸れますが、リソース設定の部分から質問いたします。
    今回のリソース設定は、「SelectionModeをGetValuesメソッドでバインドし、列挙型に格納したものを、コンボボックスがリソースとして使用している。」
    という理解で合っていますでしょうか?

    ただ、それぞれのタグやその属性で何を実行/設定しているのかが、あまり理解できませんでした。
    (ググっても理解できませんでした・・・)
    以下の理解で合っていますでしょうか?

    ・<ObjectDataProvider>・・・メソッドにバインドする
     ・x:key・・・リソースに必要なキー(値は任意)
     ・MethodName=バインドするメソッド
     ・ObjectType="{x:Type sys:Enum}" ・・・値を格納する型を指定? "sys"とは何でしょうか?

    ・<ObjectDataProvider.MethodParameters>・・・メソッドに渡すパラメータ
     ↓ここが一番分かりませんでした。↓
     ・<x:Type TypeName=○○・・・型を指定している? "controls:SelectionMode"は
    0,1,2の値なのでは???
     パラメータを指定しているのは分かりますが、
     https://docs.microsoft.com/ja-jp/dotnet/framework/wpf/data/how-to-bind-to-a-method
    を見ると、
     「system:○○」だったり「local:○○」だったり、タグが違うのもよく分かりません。

    また、https://docs.microsoft.com/ja-jp/dotnet/framework/wpf/data/how-to-bind-to-a-method
    を見ると
    BindsDirectlyToSourceを"true"にしていますが、今回はコンボボックスでBindsDirectlyToSourceを"true"にしていないのはなぜでしょうか?

    キャンセル

  • 2020/08/15 16:18

    ObjectDataProviderはかなりマニアックな機能なのでそんなに気にする必要はないですが^^;

    C#コードで言うと
    var selectionMode = Enum.GetValues(typeof(SelectionMode));
    ってのをxamlでやってる感じです。
    意味的には
    SelectionMode[] selectionMode = { SelectionMode.Single, SelectionMode.Multiple, SelectionMode.Extended };
    って感じでしょうか(これをxamlで書いたほうが短く済みますね。今気が付きました^^;

    > "sys"とは何でしょうか?
    xmlns:sys="clr-namespace:System;assembly=mscorlib"
    のsysです。つまりsys:Enumとは
    [Enum クラス (System) | Microsoft Docs](https://docs.microsoft.com/ja-jp/dotnet/api/system.enum
    のことです。
    [Enum.GetValues(Type) メソッド (System) | Microsoft Docs](https://docs.microsoft.com/ja-jp/dotnet/api/system.enum.getvalues
    を呼び出します。

    > "controls:SelectionMode"は0,1,2の値なのでは???
    値としては0,1,2ですが、SelectionModeを明示したおかげでコンボボックスに名前が出ます。

    > 「system:○○」だったり「local:○○」だったり
    system:やlocal:の部分は変数名のようなもので好きに付けられます。
    xmlns:system="clr-namespace:System;assembly=mscorlib"
    と書けばsystem:Enumとなります。

    > BindsDirectlyToSourceを"true"にしています
    私も始めて見ましたが「ObjectDataProvider自体」をバインドしたい場合(MethodParametersが欲しい)と、「メソッドを実行した結果」をバインドしたい場合(SelectionMode[]が欲しい)の違いっぽいですね。

    > お手数おかけしますがコードいただけますでしょうか。
    準備していなかったのでしばらくお待ちください^^;

    キャンセル

+1

選択されているというのが重要な情報の場合(ファイルに選択情報も保存して次回復元する等)は、別の手のほうがいいかもしれません。

Taskクラスにbool IsSelectedプロパティを用意して、lst_TitleではListBoxItemのIsSelectedにバインドし、lst_DetailではListBoxItemのVisibilityにバインドします。
どちらのListBoxもTaskListがソースですが、lst_Detailでは未選択のものは無いように見えます。
ちょっとずるいようですが、割とポピュラーな手段だと思います。もし気になるようでしたら追記しますので言ってください。

1万字に収まらなかったのでこちらで失礼します。

<Window
  x:Class="Questions284783.Views.MainWindow"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:controls="clr-namespace:System.Windows.Controls;assembly=PresentationFramework"
  xmlns:prism="http://prismlibrary.com/"
  Width="525"
  Height="350"
  prism:ViewModelLocator.AutoWireViewModel="True">
  <Window.Resources>
    <BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
  </Window.Resources>
  <Grid>
    <Grid.ColumnDefinitions>
      <ColumnDefinition />
      <ColumnDefinition Width="2*" />
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
      <RowDefinition Height="Auto" />
      <RowDefinition />
    </Grid.RowDefinitions>
    <Grid>
      <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto" />
        <ColumnDefinition />
      </Grid.ColumnDefinitions>
      <Label
        Margin="5"
        VerticalAlignment="Center"
        Content="表題" />
      <TextBox
        Grid.Column="1"
        Margin="5"
        VerticalAlignment="Center"
        Text="{Binding Txt_Title, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
        TextWrapping="Wrap" />
    </Grid>
    <Grid Grid.Column="1">
      <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto" />
        <ColumnDefinition />
        <ColumnDefinition Width="Auto" />
      </Grid.ColumnDefinitions>
      <Label
        Margin="5"
        VerticalAlignment="Center"
        Content="Memo" />
      <TextBox
        Grid.Column="1"
        Margin="5"
        VerticalAlignment="Center"
        Text="{Binding Txt_Memo, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
        TextWrapping="Wrap" />
      <Button
        Grid.Column="2"
        MinWidth="56"
        Margin="5"
        Command="{Binding ExecuteCommand}"
        Content="追加" />
    </Grid>
    <Grid Grid.Row="1">
      <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition />
      </Grid.RowDefinitions>
      <ComboBox
        x:Name="comboBox"
        Margin="5"
        SelectedIndex="0">
        <controls:SelectionMode>Single</controls:SelectionMode>
        <controls:SelectionMode>Multiple</controls:SelectionMode>
        <controls:SelectionMode>Extended</controls:SelectionMode>
      </ComboBox>
      <ListBox
        x:Name="lst_Title"
        Grid.Row="1"
        Margin="5"
        DisplayMemberPath="Title"
        IsSynchronizedWithCurrentItem="True"
        ItemsSource="{Binding TaskList}"
        SelectionMode="{Binding SelectedValue, ElementName=comboBox}">
        <ListBox.ItemContainerStyle>
          <Style TargetType="ListBoxItem">
            <Setter Property="IsSelected" Value="{Binding IsSelected}" />
          </Style>
        </ListBox.ItemContainerStyle>
      </ListBox>
    </Grid>
    <ListBox
      Grid.Row="1"
      Grid.Column="1"
      Margin="5"
      ItemsSource="{Binding TaskList}">
      <ListBox.ItemContainerStyle>
        <Style TargetType="ListBoxItem">
          <Setter Property="Visibility" Value="{Binding IsSelected, Converter={StaticResource BooleanToVisibilityConverter}}" />
        </Style>
      </ListBox.ItemContainerStyle>
      <ListBox.ItemTemplate>
        <DataTemplate>
          <StackPanel>
            <TextBlock FontWeight="Bold" Text="{Binding Title}" />
            <TextBlock Text="{Binding Detail}" />
          </StackPanel>
        </DataTemplate>
      </ListBox.ItemTemplate>
    </ListBox>
  </Grid>
</Window>
using System.Collections.ObjectModel;
using Prism.Commands;
using Prism.Mvvm;

namespace Questions284783.ViewModels
{
    public class MainWindowViewModel : BindableBase
    {
        private string txt_Title;
        public string Txt_Title
        {
            get => txt_Title;
            set { if(SetProperty(ref txt_Title, value)) ExecuteCommand.RaiseCanExecuteChanged(); }
        }

        private string txt_Memo;
        public string Txt_Memo
        {
            get => txt_Memo;
            set { if(SetProperty(ref txt_Memo, value)) ExecuteCommand.RaiseCanExecuteChanged(); }
        }

        public ObservableCollection<Task> TaskList { get; } = new ObservableCollection<Task>();
        public DelegateCommand ExecuteCommand { get; private set; }

        public MainWindowViewModel()
        {
            TaskList.Add(new Task { Title = "aaa", Detail = "111" });
            TaskList.Add(new Task { Title = "bbb", Detail = "222" });
            TaskList.Add(new Task { Title = "ccc", Detail = "333" });
            ExecuteCommand = new DelegateCommand(Execute, CanExecute);
        }

        private void Execute()
        {
            TaskList.Add(new Task { Title = Txt_Title, Detail = Txt_Memo });
            Txt_Title = "";
            Txt_Memo = "";
            ExecuteCommand.RaiseCanExecuteChanged();
        }

        private bool CanExecute() => !string.IsNullOrEmpty(Txt_Title);
    }

    public class Task : BindableBase
    {
        public string Title { get; set; }
        public string Detail { get; set; }

        private bool isSelected;
        public bool IsSelected { get => isSelected; set => SetProperty(ref isSelected, value); }
    }
}

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.06%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る