简体   繁体   中英

Listbox bound to ObservableCollection (in VB.NET and Silverlight)

Sorry if this is a duplicate question. There are quite a few questions around this topic, but I can't seem to get it figured out. I'm trying to bind a listbox to an ObservableCollection and keep the listbox updated when items are added to the collection.

I have a class called 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

Then another class where I setup the ObservableCollection of CollectionOfBlogs (above) and a sub to add items to the collection:

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

I bind the listbox to the blogNamesList collection in the ITRSBlogs Class (above) from my main page loaded event:

Dim blogClass As New ITRSBlogs

Me.BloggingMenuListBox.ItemsSource = blogClass.blogNamesList

Here is the XAML of my listbox. It's bound in the codebehind, not in the XAML (just thought I should mention that).

<ListBox Name="BloggingMenuListBox"/>

Before binding the collection to the listbox, I load the collection with items from the database, and they show up in the listbox just fine. These 2 subs below are actually in the ITRSBlogs Class as well, and I call FillBlogLists from my pages loaded event.

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

Beyond this, I have a simple textbox and button on a page. When a name is entered into the textbox, and the button is clicked, I call the addBlog(passing in name from textbox) sub routine in the ITRSBlogs Class (back up the page a bit) to add the item to the collection.

Problem is, when I add an item to the collection, the listbox is not updated. I'm new to Observable Collections (and many other things : ), so maybe I'm just really off here. Can anyone tell me what I'm doing wrong?

The code you posted looks fine to me. I replicated your code (in C#, but I tried to keep it as close to your code as possible) and it just worked. The only code you didn't post is the event handler of the Add button. Did you check that it is actually called and that a new item is added to the collection?

Anyway here is my code, maybe you can spot where the difference is between this and your version:

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);
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM