【问题标题】:ObservableCollection not updating through INotifyPropertyChangedObservableCollection 未通过 INotifyPropertyChanged 更新
【发布时间】:2023-03-31 20:28:01
【问题描述】:

我一直试图让它工作,但我仍然没有运气。基本上我正在使用 ObservableColletion 将我的所有项目加载到具有自定义 ItemTemplate 的列表框中。

这是我的 ListBox 的 XAML:

<DataTemplate x:Key="DataTemplate1">
        <Grid d:DesignWidth="431" d:DesignHeight="109.333" Height="109.333" Width="431">
            <toolkit:ContextMenuService.ContextMenu>
                <toolkit:ContextMenu IsFadeEnabled="True" IsZoomEnabled="False">
                    <toolkit:MenuItem Header="Delete" Click="Delete_Click"/>
                </toolkit:ContextMenu>
            </toolkit:ContextMenuService.ContextMenu>
            <Button x:Name="callPerson" Tag="{Binding ItemNumber}" Content="CALL" HorizontalAlignment="Left" Margin="-6,12,0,0" VerticalAlignment="Top" Click="callPerson_Click"/>
            <Grid toolkit:TiltEffect.IsTiltEnabled="True" Margin="0,-1,-121,-3">
                <TextBlock Text="{Binding ItemBody}" HorizontalAlignment="Left" VerticalAlignment="Top" Height="26" Width="387"  FontSize="19" Margin="109,62,0,0" FontFamily="Segoe WP" TextTrimming="WordEllipsis">
                    <TextBlock.Foreground>
                        <SolidColorBrush Color="{StaticResource PhoneTextMidContrastColor}"/>
                    </TextBlock.Foreground>
                </TextBlock>
                <TextBlock Text="{Binding FolderID}" HorizontalAlignment="Left" TextWrapping="Wrap" VerticalAlignment="Top" Height="34" Width="496"  FontSize="24" Margin="0,72,0,0" Visibility="Collapsed"/>
                <TextBlock Text="{Binding ItemNumber}" HorizontalAlignment="Left" VerticalAlignment="Top" Height="28" Width="387" FontSize="21" Margin="109,34,0,0" FontFamily="Segoe WP"/>
                <TextBlock Text="{Binding ItemTitle}" HorizontalAlignment="Left" VerticalAlignment="Top" Height="37" Width="387" FontSize="28" FontFamily="Segoe WP" Margin="109,0,0,0"/>
            </Grid>
        </Grid>
    </DataTemplate>

我使用 XAML 来绑定我的 ListBox,例如:ItemsSource = "{Binding}"

这是我的 INotifyPropertyChanged:

 public class Items : INotifyPropertyChanged
    {
        private string _ItemTitle;
        public string ItemTitle
        {
            get { return _ItemTitle; }
            set
            {
                _ItemTitle = value;
                RaisePropertyChangedForItemTitle("ItemTitle");
            }
        }
        private string _ItemBody;
        public string ItemBody
        {
            get { return _ItemBody; }
            set
            {
                _ItemBody = value;
                RaisePropertyChangedForItemBody("ItemBody");
            }
        }
        private string _FolderID;
        public string FolderID
        {
            get { return _FolderID; }
            set
            {
                _FolderID = value;
                RaisePropertyChangedForItemFolderID("FolderID");
            }
        }
        private string _ItemNumber;
        public string ItemNumber
        {
            get { return _ItemNumber; }
            set
            {
                _ItemNumber = value;
                RaisePropertyChangedForItemNumber("ItemNumber");
            }
        }

        public event PropertyChangedEventHandler ItemTitleChanged;
        public void RaisePropertyChangedForItemTitle(string ItemTitle)
        {
            PropertyChangedEventHandler handler = ItemTitleChanged;
            if (handler != null) handler(this, new PropertyChangedEventArgs(ItemTitle));
        }
        public event PropertyChangedEventHandler ItemBodyChanged;
        public void RaisePropertyChangedForItemBody(string ItemBody)
        {
            PropertyChangedEventHandler handler = ItemBodyChanged;
            if (handler != null) handler(this, new PropertyChangedEventArgs(ItemBody));
        }
        public event PropertyChangedEventHandler FolderIDChanged;
        public void RaisePropertyChangedForItemFolderID(string FolderID)
        {
            PropertyChangedEventHandler handler = FolderIDChanged;
            if (handler != null) handler(this, new PropertyChangedEventArgs(FolderID));
        }
        public event PropertyChangedEventHandler ItemNumberChanged;
        public void RaisePropertyChangedForItemNumber(string ItemNumber)
        {
            PropertyChangedEventHandler handler = ItemNumberChanged;
            if (handler != null) handler(this, new PropertyChangedEventArgs(ItemNumber));
        }
    }

这就是 ObservableCollection:

public class AddItems : ObservableCollection<Items>
    {
        IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication();
        public AddItems()
        {
            string directory = "/GetItems";
            string[] filenames = store.GetDirectoryNames(directory);
            foreach (string filename in filenames)
            {
                IsolatedStorageFileStream openName = store.OpenFile("/GetItems/contactName.txt", FileMode.Open, FileAccess.Read);
                IsolatedStorageFileStream openNumber = store.OpenFile("/GetItems/contactNumber.txt", FileMode.Open, FileAccess.Read);
                IsolatedStorageFileStream openFolderID = store.OpenFile("/GetItems/FolderID.txt", FileMode.Open, FileAccess.Read);
                IsolatedStorageFileStream openNotes = store.OpenFile("/GetItems/contactNotes.txt", FileMode.Open, FileAccess.Read);

                using (StreamReader readContactName = new StreamReader(openName))
                {
                    var contactName = readContactName.ReadLine();
                    using (StreamReader readContactNumber = new StreamReader(openNumber))
                    {
                        var contactNumber = readContactNumber.ReadLine();
                        using (StreamReader ReadFolderID = new StreamReader(openFolderID))
                        {
                            var FolderID = ReadFolderID.ReadLine();
                            using (StreamReader ReadContactNotes = new StreamReader(openNotes))
                            {
                                var contactNotes = ReadContactNotes.ReadLine();
                                Add(new Items() { ItemTitle = contactName, ItemBody = contactNotes, FolderID = FolderID, ItemNumber = contactNumber });
                            }
                        }
                    }
                }
            }
        }

这就是我将我的项目加载到 ListBox 中的方式:listBox.DataContext = collections.LoadItems; 我已将我的 INotifyPropertyChanged 和 ObservableCollection 添加到一个名为 Collections.cs 的不同类文件中,因此是 Collections.LoadItems。

现在我启动应用程序并加载项目。我单击一个项目,然后去编辑它,然后保存内容,然后返回主页,列表框将显示旧内容。现在让我获得编辑后的新内容,我必须关闭应用程序并重新启动它,这样它就会向我显示新内容。

这显然是不对的,因为 INotifyPropertyChanged 应该自动更改项目值等......并显示最新内容。如果有人可以帮我解决这个问题,因为我真的一无所知。不确定我是否做得对。

非常感谢! 谢谢!

【问题讨论】:

    标签: c# xaml windows-phone-8 listbox


    【解决方案1】:

    使用INotifyPropertyChanged 的模式与您使用的不同。不是为每个属性设置单独的事件,而是为任何属性更改引发一个事件:

    public class Items : INotifyPropertyChanged
    {
        // all property changes use this event
        public event PropertyChangedEventHandler PropertyChanged;
        private string _ItemTitle;
    
        // one property as an example:
        public string ItemTitle
        {
            get { return _ItemTitle; }
            set
            {
                _ItemTitle = value;
                // by using the CallerMemberName attribute
                // you can skip passing the specific property name 
                // as it's added automatically 
                RaisePropertyChanged();
            }
        }
    
        private void RaisePropertyChanged([CallerMemberName] String propertyName = "")
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }                  
    }
    

    代码肯定比你显示的多,因为如果没有事件 PropertyChanged 的声明,你的类就不会像显示的那样编译:

    public event PropertyChangedEventHandler PropertyChanged;
    

    【讨论】:

    • 谢谢。我已经实现了你给我的代码,但似乎每当我导航回主页时,它仍然显示旧内容,直到我重新启动应用程序。有什么问题?我感觉这与将项目重新加载到列表框有关?
    • 你能检查输出/调试控制台看看是否有任何绑定错误吗?
    • 没有绑定错误。如果我保存了任何项目,它会将所有项目正确加载到 ListBox 中。
    • 似乎有另一个交互可能导致它不更新。我很犹豫是否要求您显示更多代码...您实际上是如何更新列表中现有项目的数据的?
    • 基本上我使用的是独立存储。我保存了文本文件,其中包含值,因此我的 ObservableCollection 读取它们并显示它们中的每一个。我使用listBox.DataContext = collections.LoadItems; 加载所有项目。这是在Public Man() 类上。
    猜你喜欢
    • 2019-08-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-01
    相关资源
    最近更新 更多