在属性更改时更新ListView

时间:2017-07-10 10:49:18

标签: xaml uwp

我的UWP应用程序中出现了一个奇怪的问题。 我有ListView绑定到ObservableCollection<SomeInterface>。我正在更改ObservableCollection中所有项目的一个属性。问题是因为ObservableCollection没有将类作为类型参数,而是需要interface,我无法弄清楚如何在INotifyCollectionChanged上实现interface }。

所以我继续改变了集合中所有项目的属性(没有实现INotifyPropertyChanged)。这给人很奇怪的行为。当我更改属性时(我在导航到包含ListView的页面时立即执行此操作)它仅影响当前不在视图中的那些ListView项目,即,如果有100个项目ListView我可以看到前10个没有向下滚动然后那10个项目没有改变但是当我向下滚动时,我看到其他(除了前10个)ListViewItem s正在反映这些变化做了。再加上这个,当我再次向上滚动(到前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>

我的项目模板:

<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>

1 个答案:

答案 0 :(得分:1)

更改

<TextBlock Text="{x:Bind read}"/>               
<TextBlock Text="{x:Bind num}"/>    

<TextBlock Text="{x:Bind read, Mode=OneWay}"/>               
<TextBlock Text="{x:Bind num, Mode=OneWay}"/>    

实现INotifyPropertyChanged,它应该可以工作。默认情况下,x:Bind是OneTime,与传统绑定不同(因为性能/内存),因此视图中的项目不会更新。

没有INPC?您可以尝试在更改属性后在父视图上调用Bindings.Update(),但可能会丢失滚动位置。