【问题标题】:Listbox bound to ObservableCollection (in VB.NET and Silverlight)绑定到 ObservableCollection 的列表框(在 VB.NET 和 Silverlight 中)
【发布时间】:2011-01-09 05:08:05
【问题描述】:

对不起,如果这是一个重复的问题。围绕这个主题有很多问题,但我似乎无法弄清楚。我正在尝试将列表框绑定到 ObservableCollection 并在将项目添加到集合时保持列表框更新。

我有一个名为 CollectionOfBlogs 的课程:

Public Class CollectionOfBlogs
    Implements INotifyPropertyChanged

    Public Event PropertyChanged As PropertyChangedEventHandler _
    Implements INotifyPropertyChanged.PropertyChanged

    Public Sub New(ByVal name As String)
        Me.FullName = name
    End Sub

    Private _FullName As String
    Public Property FullName() As String
        Get
            Return _FullName
        End Get
        Set(ByVal value As String)
            _FullName = value
            NotifyPropertyChanged("FullName")
        End Set
    End Property

    Public Sub NotifyPropertyChanged(ByVal propertyName As String)
        RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName))
    End Sub

End Class

然后是另一个类,我设置了 CollectionOfBlogs 的 ObservableCollection(上图)和一个子类以将项目添加到集合中:

Public Class ITRSBlogs

    Public blogNamesList As New ObservableCollection(Of CollectionOfBlogs)

    Public Sub addBlog(ByVal FullName as String)
        blogNamesList.Add(New CollectionOfBlogs(FullName))
    End Sub

End Class

我通过主页加载事件将列表框绑定到 ITRSBlogs 类(上图)中的 blogNamesList 集合:

Dim blogClass As New ITRSBlogs

Me.BloggingMenuListBox.ItemsSource = blogClass.blogNamesList

这是我的列表框的 XAML。它绑定在代码隐藏中,而不是 XAML 中(只是想我应该提一下)。

<ListBox Name="BloggingMenuListBox"/>

在将集合绑定到列表框之前,我使用数据库中的项目加载集合,它们会很好地显示在列表框中。下面这两个子实际上也在 ITRSBlogs 类中,我从我的页面加载事件中调用 FillBlogLists。

Public Sub FillBlogLists()
    Dim query = theContext.GetBlogsOrderedByNameQuery
    theContext.Load(query, AddressOf OnBlogsLoaded, Nothing)
End Sub

Private Sub OnBlogsLoaded(ByVal lo As LoadOperation(Of Blog))
    blogList.Clear()
    For Each s In lo.AllEntities
        blogList.Add(CType(s, Blog))
    Next
    For Each item In blogList
        blogNamesList.Add(New CollectionOfBlogs(item.FullName))
    Next
End Sub

除此之外,我在页面上有一个简单的文本框和按钮。当在文本框中输入名称并单击按钮时,我会调用 ITRSBlogs 类中的 addBlog(passing in name from textbox) 子例程(稍微备份页面)以将项目添加到集合中。强>

问题是,当我将一个项目添加到集合中时,列表框没有更新。我是 Observable Collections 的新手(还有很多其他的东西 : ),所以也许我真的不在这里。谁能告诉我我做错了什么?

【问题讨论】:

    标签: asp.net wpf vb.net silverlight-4.0


    【解决方案1】:

    您发布的代码对我来说看起来不错。我复制了你的代码(在 C# 中,但我试图让它尽可能接近你的代码)并且它只是工作。您没有发布的唯一代码是Add 按钮的事件处理程序。您是否检查过它是否实际被调用并且是否向集合中添加了一个新项目?

    这里是我的代码,也许你可以发现这个和你的版本之间的区别:

    CollectionOfBlogs.cs:

    public class CollectionOfBlogs : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
    
        private string _FullName;
        public string FullName
        {
            get
            {
                return this._FullName;
            }
            set
            {
                if (this._FullName != value)
                {
                    this._FullName = value;
                    this.OnPropertyChanged("FullName");
                }
            }
        }
    
        public CollectionOfBlogs(string name)
        {
            this._FullName = name;
        }
    
        public virtual void OnPropertyChanged(string propertyName)
        {
            if (this.PropertyChanged != null)
            {
                this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    
        public override string ToString()
        {
            return this._FullName;
        }
    
    }
    

    ITRSBlogs.cs:

    public class ITRSBlogs
    {
        public ObservableCollection<CollectionOfBlogs> blogNamesList = new ObservableCollection<CollectionOfBlogs>();
    
        public void AddBlog(string fullName)
        {
            this.blogNamesList.Add(new CollectionOfBlogs(fullName));
        }
    
        public void FillBlogList()
        {
            this.blogNamesList.Clear();
            this.AddBlog("First blog");
            this.AddBlog("Another blog");
        }
    }
    

    MainWindow.xaml:

    <Window x:Class="ObservableRefreshDemo.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow" Height="350" Width="525" Loaded="Window_Loaded">
      <Grid>
        <ListBox Name="BloggingMenuListBox"/>
        <Button Content="Add" Height="23" HorizontalAlignment="Left" Margin="154,276,0,0" Name="button1" VerticalAlignment="Top" Width="75" Click="button1_Click" />
        <TextBox Height="23" HorizontalAlignment="Left" Margin="12,276,0,0" Name="txtName" VerticalAlignment="Top" Width="120" />
      </Grid>
    </Window>
    

    MainWindow.xaml.cs:

    public partial class MainWindow : Window
    {
    
        private ITRSBlogs blogClass = new ITRSBlogs();
    
        public MainWindow()
        {
            InitializeComponent();
        }
    
        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            this.blogClass.FillBlogList();
            this.BloggingMenuListBox.ItemsSource = this.blogClass.blogNamesList;
        }
    
        private void button1_Click(object sender, RoutedEventArgs e)
        {
            this.blogClass.AddBlog(this.txtName.Text);
        }
    }
    

    【讨论】:

    • 感谢 TomBot,我想我明白出了什么问题,但我不知道如何解决它。我确实遗漏了一些我看到的重要观点。在我的主页上,我有一个包含很多选择的菜单,其中一个选择是添加一个新博客。当您单击该按钮时,它会加载实际文本框和保存按钮所在的不同页面。因此,这个页面也有一个 Dim blogClass 作为 New ITRSBlogs,它确实调用了 addblog 方法并将文本框中的名称添加到集合中。但是,我不太了解绑定到主页上的集合的列表框是如何更新的。
    • 换句话说,我认为我有多个该系列的副本正在运行,但我不确定这一切是如何运作的。如何确保我在两个页面上查看的是同一个集合?
    • 你一定要确保你只有一个收藏。最简单的解决方案是集合在 MainPage 中,当您打开 AddDialog 时,您将引用集合到它。像 AddDialog dlg = new AddDialog(); dlg.Collection = this.Collection; dlg.ShowDialog();
    • 谢谢 TomBot,你让我找到了正确的方向。我在这里找到了一个很好的例子:Dave Corun 的博客 -davecorun.com/blog/2010/08/01/…
    猜你喜欢
    • 2018-08-13
    • 2010-12-08
    • 2011-05-07
    • 1970-01-01
    • 2012-03-20
    • 2011-05-10
    • 1970-01-01
    • 2012-04-02
    • 1970-01-01
    相关资源
    最近更新 更多