簡體   English   中英

通過INotifyPropertyChanged更新ListView的ItemsSource

[英]Updating ListView's ItemsSource via INotifyPropertyChanged

在回答其他問題的同時,我嘗試了解一件事。 我有一個ListViewItemsSource綁定到我的頁面的屬性。 頁面實現INotifyPropertyChangedDataContext設置,evrything工作,我可以看到我的列表在屏幕上呈現。 但是如果我在其中一個元素中更改某些內容並在整個集合中提升屬性,則更改在屏幕上不可見,調用getter,因此綁定有效,但沒有任何更改。

為什么會這樣? 是否有任何內部ListView的 optmization正在進行?

XAML代碼:

<StackPanel Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <ListView ItemsSource="{Binding Elements}" Height="400">
        <ListView.ItemTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding Name}" FontSize="16"/>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
    <Button Content="Modify item" Click="Button_Click"/>
</StackPanel>

代碼背后:

public class MyItem
{
    public string Name { get; set; }
    public MyItem(string name) { this.Name = name; }
}

public sealed partial class MainPage : Page, INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    public void RaiseProperty(string name) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));

    private List<MyItem> elements = new List<MyItem> { new MyItem("Standard"), new MyItem("Standard"), new MyItem("Standard") };
    public List<MyItem> Elements { get { Debug.WriteLine("Collection getter"); return elements; } }

    public MainPage()
    {
        this.InitializeComponent();
        this.DataContext = this;
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        elements[1].Name = "Modified one";
        RaiseProperty(nameof(Elements));
    }
}

注意:我知道如何通過在MyItem類中實現InotifyPropertyChanged來使其工作。 我也知道當一個項目內部發生變化時重新加載整個集合是一個糟糕的模式。 我只想確保一些事情。


其他情況 - 看起來綁定是源對象的引用副本,這很清楚。 但有趣的是,當我綁定到字符串數組時:

public string[] Elements { get; } = new string[] { "Standard", "Standard", "Standard" };

private void Button_Click(object sender, RoutedEventArgs e)
{
    Elements[1] = "Modified one";
    RaiseProperty(nameof(Elements));
}

XAML中的修改: <TextBlock Text="{Binding}" FontSize="16"/>

然后調用RaiseProperty(nameof(Elements)); 即使不修改集合,也會更新視圖。 那么為什么綁定在這種情況下以不同的方式工 它似乎只是返回數組而不檢查更改。

是的,將調用getter,因為您正在調用RaiseProperty(nameof(Elements)) 但是沒有什么會更新,因為屬性Elements 沒有變化 它仍然是完全相同的對象。 改變的是它的底層對象( elements[1] )的屬性Name

這就是為什么在這種情況下需要在MyItem級別實現InotifyPropertyChanged

如果將Elements的類型更改為ObservableCollection<MyItem> 然后,當您向/從中添加/刪除項目時,UI將更新。 但是如果底層MyItem的屬性像上面那樣改變了,那么UI仍將保持不變。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM