teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

2

移し替えたListを参照してなかった点を修正

2017/06/09 07:16

投稿

ytabuchi
ytabuchi

スコア335

answer CHANGED
@@ -30,7 +30,7 @@
30
30
 
31
31
  ```csharp
32
32
  var tempList = ar.Select(x => x).ToList();
33
- var i = ar.IndexOf(((MyCell)e.SelectedItem));
33
+ var i = tempList.IndexOf(((MyCell)e.SelectedItem));
34
34
  tempList[i].Text = "changed";
35
35
  ar.Clear();
36
36
  foreach (var item in tempList)

1

コメントを受けて回答を修正しました

2017/06/09 07:16

投稿

ytabuchi
ytabuchi

スコア335

answer CHANGED
@@ -1,4 +1,44 @@
1
1
  こんにちは。
2
2
 
3
3
  e.SelectedItemはセルに指定したクラスのオブジェクトが取れるので、
4
- `((MyCell)e.SelectedItem).Name` みたいにキャストしてプロパティを取ってこれたはずです。
4
+ `((MyCell)e.SelectedItem).Name` みたいにキャストしてプロパティを取ってこれたはずです。
5
+
6
+ コメントを見て、回答を以下にアップデートします。
7
+
8
+ ---
9
+ ListViewからではなく、ItemsSourceに指定しているコレクションarを直接操作することになるかと思います。
10
+
11
+ `List<MyCell> ar` をフィールドにして、該当のメソッド内で
12
+
13
+ ```csharp
14
+ var i = ar.IndexOf(((MyCell)e.SelectedItem));
15
+ ar[i].Text = "changed";
16
+ ```
17
+ とすると取り敢えずプロパティを書き換えることはできるんですが、ListView自体の書き換えが必要になってしまいます。Xamarin.Formsの`ListView`には`CollectionChanged`を受け取って自動で表示を更新する機能があります。そのため、通常は`List<T>`の代わりに内容が変わると`CollectionChanged`を発火してくれる`ObservabaleCollection<T>`を使用します。
18
+
19
+ ところが、今回やっているのはプロパティの変更なので、`CollectionChanged`ではなく、`PropertyChanged`が発火してしまい、`CollectionChanged`が発火しません。
20
+
21
+ これらを回避して簡単そうな方法だと、
22
+
23
+ 1. フィールド`ObservableCollection<MyCell> ar;`を作成
24
+ 1. コレクションを一時的なコレクションに格納して
25
+ 1. インデックスを指定して値を書きかえ
26
+ 1. 元のコレクションをクリアして(←この時点でCollectionChangedが発火(するはず))
27
+ 1. 一時的なコレクションから全データを元のコレクションに流し込む(←この時点でもCollectionChangedが発火)
28
+
29
+ という感じになるかと思います。
30
+
31
+ ```csharp
32
+ var tempList = ar.Select(x => x).ToList();
33
+ var i = ar.IndexOf(((MyCell)e.SelectedItem));
34
+ tempList[i].Text = "changed";
35
+ ar.Clear();
36
+ foreach (var item in tempList)
37
+ {
38
+ ar.Add(new MyCell { No = item.No, Text = item.Text });
39
+ }
40
+ ```
41
+
42
+ 他にもステキな書き方があるかと思いますので、他の方からの回答を待っても良いかと。
43
+
44
+ ---