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

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

新規登録して質問してみよう
ただいま回答率
85.49%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

WPF

Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

Q&A

解決済

2回答

3220閲覧

MVVMパターンのWPFアプリケーションでListViewのカラムを動的に追加したい

siksmtt

総合スコア20

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

WPF

Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

0グッド

1クリップ

投稿2019/02/26 06:52

WPFアプリケーションをMVVMパターンで作っています。

ListViewのカラムを動的に追加したく色々試しているのですが、上手くいっておりません。

Xaml

1//View 2 <Button Content="追加する" HorizontalAlignment="Left" Height="76" Margin="72,192,0,0" VerticalAlignment="Top" Width="135" Click="OnClickAdd"/> 3 4 <ListView Margin="221,113,30,78" ItemsSource="{Binding ListSource}"> 5 <ListView.View> 6 <GridView> 7 <GridViewColumn Header="{Binding HeaderName}" Width="70" DisplayMemberBinding="{Binding Item}" /> 8 </GridView> 9 </ListView.View> 10 </ListView>

C#

1//コードビハインド 2 public MainWindow() 3 { 4 InitializeComponent(); 5 mMainViewModel = new MainViewModel(); 6 this.DataContext = mMainViewModel; 7 8 ColumnItem columnItem = new ColumnItem(); 9 columnItem.HeaderName = DateTime.Now.Second.ToString(); 10 columnItem.Item = "Item"; 11 12 mMainViewModel.ListSource.Add(columnItem); 13 } 14 15 private void OnClickAdd(object sender, RoutedEventArgs e) 16 { 17 var array = mMainViewModel.ListSource; 18 19 ColumnItem columnItem = new ColumnItem(); 20 columnItem.HeaderName = DateTime.Now.Second.ToString(); 21 columnItem.Item = "Item"; 22 23 array.Add(columnItem); 24 25 mMainViewModel.ListSource = array; 26 }

C#

1//ViewModel 2 private ObservableCollection<ColumnItem> listSourceValue = new ObservableCollection<ColumnItem>(); 3 public ObservableCollection<ColumnItem> ListSource 4 { 5 get 6 { 7 return listSourceValue; 8 } 9 set 10 { 11 listSourceValue = value; 12 NotifyPropertyChanged("ListSource"); 13 } 14 }

サンプルなので完全なMVVMではないですが、"追加する"ボタンが押下される毎にListViewにカラムを追加したいと思っています。
ただ上記プログラムだと「Item」という行が追加されるだけになってしまいます。

DataGridでもいいのですが、MVVMパターンで動的にカラムを追加する方法はないでしょうか?
ちなみに追加するカラム数の上限は決まっています。

ご助言いただけますと幸いです。

気になる質問をクリップする

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

提示されているコードだと、リスト内に表示するデータをAddしているので、行が増えます。
私が知っているのはDataGridのやり方なのでDataGridについて説明させてもらいます。
DataGridに列を追加する場合は、それ自体に働き掛けないといけないです。
例えば、ListViewを<DataGrid x:Name="sampleGrid" Margin="221,113,30,78" ItemsSource="{Binding ListSource}" />のように変更して以下のようにするととりあえずはボタンを押したときにColumn3が増えると思います。ListViewも似たようなことが出来た気がします。

C#

1// View 2public MainWindow() 3{ 4 InitializeComponent(); 5 DataContext = new MainViewModel(); 6 7 sampleGrid.AutoGenerateColumns = false; // 列の自動生成を停止(これと) 8 sampleGrid.Columns.Clear(); // 自動生成された列を削除(これは必須ではない) 9 sampleGrid.Columns.Add(new DataGridTextColumn() { Header = "Column1", Binding = new Binding("Column1") }); 10 sampleGrid.Columns.Add(new DataGridTextColumn() { Header = "Column2", Binding = new Binding("Column2") }); 11 12} 13private void OnClickAdd(object sender, RoutedEventArgs e) 14{ 15 sampleGrid.Columns.Add(new DataGridTextColumn() { Header = "Column3", Binding = new Binding("Column3") }); 16}

C#

1// ViewModel 2public class GridItem 3{ 4 public string Column1 { get; set; } 5 public string Column2 { get; set; } 6 public string Column3 { get; set; } 7} 8internal MainViewModel() 9{ 10 listSourceValue.Add(new GridItem() { Column1 = "C1_1", Column2 = "C2_1", Column3 = "C3_1" }); 11 listSourceValue.Add(new GridItem() { Column1 = "C1_2", Column2 = "C2_2", Column3 = "C3_2" }); 12} 13 14// これはあくまでもList内に表示するデータ 15private ObservableCollection<GridItem> listSourceValue = new ObservableCollection<GridItem>(); 16public ObservableCollection<GridItem> ListSource{}

ViewでColumns.Addをしない場合(完全なMVVMを目指す場合)は、多分CustomTypeDescriptorを使う方法が一番MVVMっぽい感じに(コードビハインド無しで、Model(or VM)だけで完結できるように)なるんだと思います。
DataGridは自動でプロパティを確認して、プロパティ名をヘッダ名とした列を生成してくれます。CustomTypeDescriptorを使うと、プロパティを任意に変更できると思って頂ければよろしいかと思います。
ただ、複雑になりやすいので、私はそこまではせず、上記のような感じで済ませてしまうことが殆どです。

あと、これは余計な御世話かもしれませんが、複数のものを並べるとき、マージンで頑張って調整するのはよろしくないと思います。

投稿2019/02/26 07:48

moredeep

総合スコア1507

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

siksmtt

2019/02/26 08:37

moredeep様 ご丁寧にコードまでありがとうございます、とても助かります!DataGridは試していなかったのですが、ListViewもそのようにコードビハインド(View)から処理するようになってしまうので、似たようになってしまうのですね...。ただCustomTypeDescriptorは試してなかったので余力があれば試してみようと思います!
siksmtt

2019/02/26 08:40

マージンの件ですが、ご指摘ありがとうございます。UIの方は全く手をつけられていなかったので、マージンなど気にせず書いていました。すぐに直しておこうと思います!
guest

0

ListViewにそんな機能はないしカスタマイズもしにくいので、ItemsControlから作ったほうが速いぐらいです。
DataGridなら、AutoGenerateColumns="True"で、
ItemsSource にBindしたコレクションの元のクラスのプロパティに対応したカラムを作ってくれます。
DataGridのItemsSource をごっそり入れ替えれば、動的っぽく変更できるでしょう。

投稿2019/02/26 07:55

hihijiji

総合スコア4150

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

siksmtt

2019/02/26 08:47

hihijiji様 いつもご助言ありがとうございます。やはり機能としてないのですね...。2日かけても出てこなかったのでまさかとは思いましたが...潔くListViewは諦めることにします。AutoGenerateColumnsについて少し調べてみましたが、たしかにできそうです。明日にでも確認してみます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.49%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問