私のUWPアプリケーションで奇妙な問題が発生しています。 ObservableCollection<SomeInterface>
にはListView
がバインドされています。私はObservableCollection
のすべてのアイテムの1つのプロパティを変更しています。問題は、ObservableCollection
がタイプ引数としてクラスを取らず、むしろinterface
を受け取り、interface
にINotifyCollectionChanged
を実装する方法を理解できないということです。プロパティの変更でListViewを更新する
私は先に進み、コレクション内のすべてのアイテムのプロパティを変更しました(INotifyPropertyChanged
を実装せずに)。これは奇妙な行動を起こしています。私がプロパティを変更するとき(ListView
を含むページに移動するとすぐにこれを行います)ListView
に100個のアイテムがあり、最初のものが表示されている場合は、表示されていないアイテム10をスクロールせずに10の項目は変更されませんが、下にスクロールすると、他の(最初の10以外の)ListViewItem
は変更が反映されています。そしてこれに加えて、私が(最初の10項目に)上にスクロールすると、今も変わっていることがわかります。
要約すると、現在表示されていない項目のみが更新されます。ここ
はObservableCollection
を更新するために私のコードです:
class SomePage : Page
{
private ObservabeCollection<SomeInterface> SomeObservableCollection { get; set; } = new ObservabeCollection<SomeInterface>();
...
private async Task ModifyObservableCollection()
{
var response = await MakeApiCall();
var facets = response.ListOfItems;
foreach (var item in SomeObservableCollection.ToList())
{
var fromApi = facets.author.FirstOrDefault(i => i.key == item.key);
if (fromApi == null) continue;
var itemInList = SomeList.FirstOrDefault(i => i.key == fromApi.key);
itemInList.read = fromApi.read;
itemInList.num = fromApi.num;
//here!!
itemInList = SomeObservableCollection.FirstOrDefault(i => i.key == fromApi.key);
itemInList.read = fromApi.read;
itemInList.num = fromApi.num;
}
}
}
これは私のListViewです:
<ListView ItemsSource="{x:Bind AuthorFacets, Mode=OneWay}"
ItemTemplate="{StaticResource ListViewDataTemplate}"
SelectionMode="Multiple">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
</Style>
</ListView.ItemContainerStyle>
</ListView>
マイItemTemplateに:
<DataTemplate x:Key="ListViewDataTemplate"
x:DataType="local:ISomeInterface">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="Auto"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock Text="{x:Bind read}"/>
<TextBlock Text="{x:Bind num}"/>
</Grid>
</DataTemplate>
あなたは2つのことをする必要があります。まず、readおよびnumプロパティを所有するクラスでINotifyPropertyChangedを実装します(プロパティ値が変更されたときに実際にPropertyChangedイベントが発生します)。二番目に、 'Mode = OneWay'を' x:Bind'宣言に追加してください。なぜなら、デフォルトは 'OneTime'であるからです(あるいは' {Binding ...} 'に変更する)。 – Clemens
'ListView'はデフォルトで仮想化をオンにしています。あなたは 'OneTime'バインディングを使用しているので、既に実現されているリストビュー項目は単に更新されません。しかし、実現しようとしているものについては、初めて新しいデータが入力されます。理にかなっている? –
私は上下にスクロールすると、なぜこれは機能しますか? –